geoblacklight_admin 0.5.1 → 0.6.0
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 +18 -9
- data/Rakefile +83 -47
- data/app/assets/javascripts/geoblacklight_admin/chosen.js +1 -0
- data/app/assets/stylesheets/geoblacklight_admin/_core.scss +24 -0
- data/app/assets/stylesheets/geoblacklight_admin/modules/_nav.scss +0 -5
- data/app/assets/stylesheets/geoblacklight_admin/modules/_tables.scss +1 -1
- data/app/controllers/admin/admin_controller.rb +16 -0
- data/app/controllers/admin/advanced_search_controller.rb +1 -1
- data/app/controllers/admin/assets_controller.rb +41 -5
- data/app/controllers/admin/bookmarks_controller.rb +14 -2
- data/app/controllers/admin/bulk_actions_controller.rb +31 -0
- data/app/controllers/admin/document_accesses_controller.rb +38 -0
- data/app/controllers/admin/document_assets_controller.rb +46 -9
- data/app/controllers/admin/document_distributions_controller.rb +172 -0
- data/app/controllers/admin/documents_controller.rb +41 -55
- data/app/controllers/admin/elements_controller.rb +22 -0
- data/app/controllers/admin/form_elements_controller.rb +31 -0
- data/app/controllers/admin/import_documents_controller.rb +11 -1
- data/app/controllers/admin/imports_controller.rb +32 -2
- data/app/controllers/admin/mappings_controller.rb +15 -0
- data/app/controllers/admin/notifications_controller.rb +27 -0
- data/app/controllers/admin/reference_types_controller.rb +106 -0
- data/app/controllers/admin/search_controller.rb +7 -0
- data/app/controllers/admin/users_controller.rb +10 -0
- data/app/helpers/asset_helper.rb +6 -0
- data/app/helpers/bulk_actions_helper.rb +9 -0
- data/app/helpers/document_helper.rb +36 -0
- data/app/helpers/geoblacklight_admin_helper.rb +88 -8
- data/app/helpers/mappings_helper.rb +26 -0
- data/app/indexers/document_indexer.rb +22 -2
- data/app/javascript/channels/consumer.js +6 -0
- data/app/javascript/channels/export_channel.js +30 -0
- data/app/javascript/channels/index.js +3 -0
- data/app/javascript/controllers/results_controller.js +14 -0
- data/app/javascript/index.js +8 -2
- data/app/jobs/export_job.rb +35 -8
- data/app/jobs/geoblacklight_admin/delete_thumbnail_job.rb +19 -0
- data/app/jobs/geoblacklight_admin/remove_parent_dct_references_uri_job.rb +16 -0
- data/app/jobs/geoblacklight_admin/set_parent_dct_references_uri_job.rb +17 -0
- data/app/jobs/geoblacklight_admin/store_image_job.rb +22 -0
- data/app/models/asset.rb +20 -0
- data/app/models/bulk_action.rb +2 -1
- data/app/models/document/geom_validator.rb +8 -0
- data/app/models/document/reference.rb +65 -65
- data/app/models/document.rb +128 -71
- data/app/models/document_distribution.rb +145 -0
- data/app/models/element.rb +2 -0
- data/app/models/geoblacklight_admin/schema.rb +10 -2
- data/app/models/import_document_state_machine.rb +1 -0
- data/app/models/reference_type.rb +40 -0
- data/app/models/user.rb +4 -2
- data/app/services/export_csv_document_distributions_service.rb +61 -0
- data/app/services/geoblacklight_admin/image_service/tms.rb +0 -4
- data/app/services/geoblacklight_admin/image_service.rb +1 -1
- data/app/services/geoblacklight_admin/item_viewer.rb +4 -4
- data/app/views/admin/bulk_actions/show.html.erb +1 -1
- data/app/views/admin/document_accesses/import.html.erb +6 -2
- data/app/views/admin/document_assets/_assets_table.html.erb +49 -0
- data/app/views/admin/document_assets/_form.html.erb +2 -3
- data/app/views/admin/document_assets/index.html.erb +1 -47
- data/app/views/admin/document_distributions/_document_distribution.html.erb +39 -0
- data/app/views/admin/document_distributions/_document_distribution.json.jbuilder +2 -0
- data/app/views/admin/document_distributions/_form.html.erb +34 -0
- data/app/views/admin/document_distributions/destroy_all.html.erb +82 -0
- data/app/views/admin/document_distributions/edit.html.erb +12 -0
- data/app/views/admin/document_distributions/import.html.erb +80 -0
- data/app/views/admin/document_distributions/index.html.erb +143 -0
- data/app/views/admin/document_distributions/index.json.jbuilder +1 -0
- data/app/views/admin/document_distributions/new.html.erb +11 -0
- data/app/views/admin/document_distributions/show.html.erb +10 -0
- data/app/views/admin/document_distributions/show.json.jbuilder +1 -0
- data/app/views/admin/documents/_document.html.erb +1 -3
- data/app/views/admin/documents/_form.html.erb +2 -4
- data/app/views/admin/documents/_form_control.html.erb +5 -2
- data/app/views/admin/documents/_form_nav.html.erb +14 -5
- data/app/views/admin/documents/_form_nav_kithe.html.erb +4 -1
- data/app/views/admin/documents/_json_aardvark.jbuilder +1 -1
- data/app/views/admin/documents/_json_gbl_v1.jbuilder +1 -1
- data/app/views/admin/documents/_result_selected_options.html.erb +5 -2
- data/app/views/admin/documents/admin.html.erb +5 -5
- data/app/views/admin/documents/features/_document_references.html.erb +23 -0
- data/app/views/admin/documents/features/_multiple_download_links.html.erb +29 -26
- data/app/views/admin/ids/fetch.json.jbuilder +0 -2
- data/app/views/admin/ids/index.json.jbuilder +0 -2
- data/app/views/admin/imports/_form.html.erb +1 -1
- data/app/views/admin/imports/show.html.erb +1 -1
- data/app/views/admin/layouts/application.html.erb +4 -2
- data/app/views/admin/reference_types/_form.html.erb +25 -0
- data/app/views/admin/reference_types/_reference_type.html.erb +52 -0
- data/app/views/admin/reference_types/_reference_type.json.jbuilder +2 -0
- data/app/views/admin/reference_types/edit.html.erb +12 -0
- data/app/views/admin/reference_types/index.html.erb +52 -0
- data/app/views/admin/reference_types/index.json.jbuilder +1 -0
- data/app/views/admin/reference_types/new.html.erb +11 -0
- data/app/views/admin/reference_types/show.html.erb +3 -0
- data/app/views/admin/reference_types/show.json.jbuilder +1 -0
- data/app/views/admin/shared/_footer.html.erb +5 -2
- data/app/views/admin/shared/_js_behaviors.html.erb +2 -3
- data/app/views/admin/shared/_navbar.html.erb +9 -2
- data/app/views/admin/users/index.html.erb +0 -1
- data/app/views/catalog/_show_gbl_admin.html.erb +1 -1
- data/config/initializers/defaults.yml +310 -0
- data/config/initializers/rails_config.rb +8 -0
- data/config/locales/documents.en.yml +14 -0
- data/config/routes.rb +30 -5
- data/db/import_references_schema_support.numbers +0 -0
- data/db/migrate/20230316183001_add_geoblacklight_admin_gem.rb +0 -12
- data/db/migrate/20241009200524_create_admin_reference_types.rb +13 -0
- data/db/migrate/20241010161420_create_document_references.rb +14 -0
- data/db/migrate/20241120238823_rename_references_to_distributions.rb +5 -0
- data/db/seeds.rb +5 -0
- data/db/seeds_elements.csv +1 -1
- data/db/seeds_elements.numbers +0 -0
- data/db/seeds_reference_types.csv +29 -0
- data/db/seeds_reference_types.numbers +0 -0
- data/db/structure.sql +1 -38
- data/lib/compose.yml +31 -0
- data/lib/generators/geoblacklight_admin/config_generator.rb +48 -12
- data/lib/generators/geoblacklight_admin/install_generator.rb +8 -0
- data/lib/generators/geoblacklight_admin/templates/config/database.yml +1 -1
- data/lib/generators/geoblacklight_admin/templates/config/initializers/devise.rb +0 -2
- data/lib/generators/geoblacklight_admin/templates/config/initializers/mime_types.rb +1 -0
- data/lib/generators/geoblacklight_admin/templates/demo-app/Dockerfile +31 -0
- data/lib/generators/geoblacklight_admin/templates/demo-app/compose.yml +42 -0
- data/lib/generators/geoblacklight_admin/templates/demo-app/start-server.sh +21 -0
- data/lib/geoblacklight_admin/engine.rb +4 -0
- data/lib/geoblacklight_admin/tasks/distributions.rake +69 -0
- data/lib/geoblacklight_admin/tasks/images.rake +1 -0
- data/lib/geoblacklight_admin/tasks/solr.rake +31 -0
- data/lib/geoblacklight_admin/version.rb +1 -1
- data/lib/geoblacklight_admin.rb +4 -0
- metadata +78 -41
- data/app/javascript/entrypoints/engine.js +0 -8
- data/config/locales/devise_invitable.en.yml +0 -31
- data/lib/generators/geoblacklight_admin/templates/devise/invitations/edit.html.erb +0 -15
- data/lib/generators/geoblacklight_admin/templates/devise/invitations/new.html.erb +0 -15
- data/lib/generators/geoblacklight_admin/templates/devise/mailer/invitation_instructions.html.erb +0 -11
- data/lib/generators/geoblacklight_admin/templates/devise/mailer/invitation_instructions.text.erb +0 -11
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "csv"
|
|
4
|
+
|
|
5
|
+
# DocumentDistribution
|
|
6
|
+
#
|
|
7
|
+
# This class represents a distribution of a document, which includes a URL and a distribution type.
|
|
8
|
+
# It belongs to a document and a reference type, and it supports CSV import and export.
|
|
9
|
+
#
|
|
10
|
+
# Associations:
|
|
11
|
+
# - belongs_to :document
|
|
12
|
+
# - belongs_to :reference_type
|
|
13
|
+
#
|
|
14
|
+
# Callbacks:
|
|
15
|
+
# - after_save :reindex_document
|
|
16
|
+
#
|
|
17
|
+
# Validations:
|
|
18
|
+
# - Validates presence of :friendlier_id, :reference_type_id, :url
|
|
19
|
+
# - Validates uniqueness of :url scoped to :friendlier_id and :reference_type_id
|
|
20
|
+
#
|
|
21
|
+
# Scopes:
|
|
22
|
+
# - to_aardvark_distributions: Converts distributions to aardvark format
|
|
23
|
+
# - to_csv: Converts distributions to CSV format
|
|
24
|
+
class DocumentDistribution < ApplicationRecord
|
|
25
|
+
belongs_to :document, foreign_key: :friendlier_id, primary_key: :friendlier_id
|
|
26
|
+
belongs_to :reference_type
|
|
27
|
+
after_save :reindex_document
|
|
28
|
+
|
|
29
|
+
# Validations
|
|
30
|
+
validates :friendlier_id, :reference_type_id, :url, presence: true
|
|
31
|
+
validates :url, uniqueness: {scope: [:friendlier_id, :reference_type_id]}
|
|
32
|
+
|
|
33
|
+
# Scopes
|
|
34
|
+
scope :to_aardvark_distributions, -> {
|
|
35
|
+
distributions = where(friendlier_id: pluck(:friendlier_id)).map(&:to_aardvark_distribution)
|
|
36
|
+
merged = {}
|
|
37
|
+
distributions.each do |dist|
|
|
38
|
+
if dist.keys.first == "http://schema.org/downloadUrl"
|
|
39
|
+
merged["http://schema.org/downloadUrl"] ||= []
|
|
40
|
+
merged["http://schema.org/downloadUrl"] << {
|
|
41
|
+
"url" => dist.values.first,
|
|
42
|
+
"label" => dist[:label]
|
|
43
|
+
}
|
|
44
|
+
else
|
|
45
|
+
merged[dist.keys.first] = dist.values.first
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
merged
|
|
49
|
+
}
|
|
50
|
+
scope :to_csv, -> { where(friendlier_id: pluck(:friendlier_id)).map(&:to_csv) }
|
|
51
|
+
|
|
52
|
+
# CSV Column Names
|
|
53
|
+
#
|
|
54
|
+
# Returns an array of column names for CSV export.
|
|
55
|
+
#
|
|
56
|
+
# @return [Array<String>] the CSV column names
|
|
57
|
+
def self.csv_column_names
|
|
58
|
+
["friendlier_id", "reference_type", "distribution_url", "label"]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Import
|
|
62
|
+
#
|
|
63
|
+
# Imports document distributions from a CSV file.
|
|
64
|
+
#
|
|
65
|
+
# @param file [File] the CSV file to import
|
|
66
|
+
# @return [Boolean] true if import is successful
|
|
67
|
+
def self.import(file)
|
|
68
|
+
logger.debug("CSV Import")
|
|
69
|
+
::CSV.foreach(file.path, headers: true) do |row|
|
|
70
|
+
logger.debug("CSV Row: #{row.to_hash}")
|
|
71
|
+
document_distribution = DocumentDistribution.find_or_initialize_by(
|
|
72
|
+
friendlier_id: row.to_hash["friendlier_id"],
|
|
73
|
+
reference_type_id: ReferenceType.find_by(name: row.to_hash["reference_type"]).id,
|
|
74
|
+
url: row.to_hash["distribution_url"],
|
|
75
|
+
label: row.to_hash["label"]
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
logger.debug("Document Distribution: #{document_distribution.inspect}")
|
|
79
|
+
|
|
80
|
+
document_distribution.update!(
|
|
81
|
+
friendlier_id: row.to_hash["friendlier_id"],
|
|
82
|
+
reference_type_id: ReferenceType.find_by(name: row.to_hash["reference_type"]).id,
|
|
83
|
+
url: row.to_hash["distribution_url"],
|
|
84
|
+
label: row.to_hash["label"]
|
|
85
|
+
)
|
|
86
|
+
end
|
|
87
|
+
true
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Destroy All
|
|
91
|
+
#
|
|
92
|
+
# Destroys document distributions based on a CSV file.
|
|
93
|
+
#
|
|
94
|
+
# @param file [File] the CSV file to process
|
|
95
|
+
# @return [Boolean] true if destroy is successful
|
|
96
|
+
def self.destroy_all(file)
|
|
97
|
+
logger.debug("CSV Destroy")
|
|
98
|
+
::CSV.foreach(file.path, headers: true) do |row|
|
|
99
|
+
logger.debug("CSV Row: #{row.to_hash}")
|
|
100
|
+
if DocumentDistribution.destroy_by(
|
|
101
|
+
friendlier_id: row.to_hash["friendlier_id"],
|
|
102
|
+
reference_type_id: ReferenceType.find_by(name: row.to_hash["reference_type"]).id,
|
|
103
|
+
url: row.to_hash["distribution_url"]
|
|
104
|
+
)
|
|
105
|
+
logger.debug("Destroyed: #{row.to_hash}")
|
|
106
|
+
else
|
|
107
|
+
logger.debug("Not Destroyed: #{row.to_hash}")
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
true
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# To CSV
|
|
114
|
+
#
|
|
115
|
+
# Converts the document distribution to an array suitable for CSV export.
|
|
116
|
+
#
|
|
117
|
+
# @return [Array<String>] the CSV row data
|
|
118
|
+
def to_csv
|
|
119
|
+
[
|
|
120
|
+
friendlier_id,
|
|
121
|
+
reference_type.name,
|
|
122
|
+
url,
|
|
123
|
+
label
|
|
124
|
+
]
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# To Aardvark Reference
|
|
128
|
+
#
|
|
129
|
+
# Converts the document distribution to an aardvark distribution format.
|
|
130
|
+
#
|
|
131
|
+
# @return [Hash] the aardvark reference
|
|
132
|
+
def to_aardvark_distribution
|
|
133
|
+
hash = {}
|
|
134
|
+
hash[reference_type.reference_uri.to_s] = url
|
|
135
|
+
hash[:label] = label if reference_type.reference_uri.to_s == "http://schema.org/downloadUrl"
|
|
136
|
+
hash
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Reindex Document
|
|
140
|
+
#
|
|
141
|
+
# Reindexes the associated document.
|
|
142
|
+
def reindex_document
|
|
143
|
+
document.save
|
|
144
|
+
end
|
|
145
|
+
end
|
data/app/models/element.rb
CHANGED
|
@@ -31,7 +31,11 @@ module GeoblacklightAdmin
|
|
|
31
31
|
}
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
unless ENV["GBL_ADMIN_REFERENCES_MIGRATED"] == "true"
|
|
35
|
+
Rails.logger.warn("Deprecation warning: AttrJSON-based dct_references_s will not be supported soon.")
|
|
36
|
+
@fields = @fields.merge(dct_references_import_mappings)
|
|
37
|
+
end
|
|
38
|
+
|
|
35
39
|
@fields
|
|
36
40
|
end
|
|
37
41
|
|
|
@@ -63,7 +67,11 @@ module GeoblacklightAdmin
|
|
|
63
67
|
}
|
|
64
68
|
}
|
|
65
69
|
|
|
66
|
-
|
|
70
|
+
unless ENV["GBL_ADMIN_REFERENCES_MIGRATED"] == "true"
|
|
71
|
+
Rails.logger.warn("Deprecation warning: AttrJSON-based dct_references_s will not be supported soon.")
|
|
72
|
+
@fields = @fields.merge(dct_references_import_mappings)
|
|
73
|
+
end
|
|
74
|
+
|
|
67
75
|
@fields = @fields.merge(object_metadata)
|
|
68
76
|
@fields
|
|
69
77
|
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# The ReferenceType class represents a reference entity in the application.
|
|
4
|
+
# It includes validations for presence and uniqueness of reference attributes,
|
|
5
|
+
# and manages the position of references within the system.
|
|
6
|
+
class ReferenceType < ApplicationRecord
|
|
7
|
+
has_many :document_distributions, dependent: :destroy
|
|
8
|
+
|
|
9
|
+
# Validations
|
|
10
|
+
# Ensures that both reference_type and reference_uri are present and unique.
|
|
11
|
+
validates :name, :reference_type, :reference_uri, presence: true
|
|
12
|
+
validates :name, :reference_type, uniqueness: true
|
|
13
|
+
|
|
14
|
+
# Callbacks
|
|
15
|
+
# Sets the position of the reference before it is created.
|
|
16
|
+
before_create :set_last_position
|
|
17
|
+
|
|
18
|
+
# Sets the position of the reference to the next available position.
|
|
19
|
+
# If no references exist, it sets the position to 1.
|
|
20
|
+
#
|
|
21
|
+
# @return [void]
|
|
22
|
+
def set_last_position
|
|
23
|
+
position = ReferenceType.all.order(position: :desc)&.first&.position
|
|
24
|
+
self.position = position.blank? ? 1 : position + 1
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Class method to sort elements based on an array of IDs.
|
|
28
|
+
# Updates the position of each ReferenceType according to the order in the array.
|
|
29
|
+
#
|
|
30
|
+
# @param id_array [Array<Integer>] An array of element IDs to be sorted.
|
|
31
|
+
# @return [void]
|
|
32
|
+
def self.sort_elements(id_array)
|
|
33
|
+
transaction do
|
|
34
|
+
logger.debug { id_array.inspect }
|
|
35
|
+
id_array.each_with_index do |elm_id, i|
|
|
36
|
+
ReferenceType.update(elm_id, position: i)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
data/app/models/user.rb
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "devise"
|
|
4
|
+
|
|
3
5
|
# User
|
|
4
6
|
class User < ApplicationRecord
|
|
7
|
+
extend Devise::Models
|
|
5
8
|
include Blacklight::User
|
|
6
9
|
|
|
7
10
|
# Include default devise modules. Others available are:
|
|
8
11
|
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
|
|
9
|
-
devise :
|
|
10
|
-
:recoverable, :rememberable, :validatable
|
|
12
|
+
devise :database_authenticatable, :recoverable, :rememberable, :validatable
|
|
11
13
|
|
|
12
14
|
has_many :bookmarks, dependent: :destroy, as: :user
|
|
13
15
|
has_many :notifications, dependent: :destroy, as: :recipient
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "csv"
|
|
4
|
+
|
|
5
|
+
# ExportCsvDocumentDistributionsService
|
|
6
|
+
#
|
|
7
|
+
# This service is responsible for exporting document distributions to a CSV format.
|
|
8
|
+
# It broadcasts the progress of the export process via ActionCable.
|
|
9
|
+
class ExportCsvDocumentDistributionsService
|
|
10
|
+
# Returns a short name for the service.
|
|
11
|
+
#
|
|
12
|
+
# @return [String] the short name of the service.
|
|
13
|
+
def self.short_name
|
|
14
|
+
"Document Distributions"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Initiates the CSV export process for the given document IDs.
|
|
18
|
+
#
|
|
19
|
+
# @param document_ids [Array] an array of document IDs to export.
|
|
20
|
+
# @return [Array] the generated CSV file content as an array of rows.
|
|
21
|
+
#
|
|
22
|
+
# This method broadcasts the progress of the export process to the "export_channel".
|
|
23
|
+
# It processes the document IDs in slices and handles any NoMethodError exceptions
|
|
24
|
+
# that occur during the export process.
|
|
25
|
+
def self.call(document_ids)
|
|
26
|
+
ActionCable.server.broadcast("export_channel", {progress: 0})
|
|
27
|
+
|
|
28
|
+
document_ids = document_ids.flatten
|
|
29
|
+
total = document_ids.size
|
|
30
|
+
count = 0
|
|
31
|
+
slice_count = 100
|
|
32
|
+
csv_file = []
|
|
33
|
+
|
|
34
|
+
Rails.logger.debug { "\n\nExportCsvDocumentDistributionsService: #{document_ids.inspect}\n\n" }
|
|
35
|
+
|
|
36
|
+
CSV.generate(headers: true) do |_csv|
|
|
37
|
+
csv_file << DocumentDistribution.csv_column_names
|
|
38
|
+
document_ids.each_slice(slice_count) do |slice|
|
|
39
|
+
# Broadcast progress percentage
|
|
40
|
+
count += slice_count
|
|
41
|
+
progress = ((count.to_f / total) * 100).round
|
|
42
|
+
progress = 100 if progress > 100
|
|
43
|
+
|
|
44
|
+
ActionCable.server.broadcast("export_channel", {progress: progress})
|
|
45
|
+
slice.each do |doc_id|
|
|
46
|
+
doc = Document.find_by(friendlier_id: doc_id)
|
|
47
|
+
|
|
48
|
+
Rails.logger.debug { "\n\nDocDistributions: #{doc.document_distributions.size}\n\n" }
|
|
49
|
+
|
|
50
|
+
doc.document_distributions.each do |distribution|
|
|
51
|
+
csv_file << distribution.to_csv
|
|
52
|
+
end
|
|
53
|
+
rescue NoMethodError
|
|
54
|
+
Rails.logger.debug { "\n\nExport Failed: #{doc_id.inspect}\n\n" }
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
csv_file
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -23,16 +23,12 @@ module GeoblacklightAdmin
|
|
|
23
23
|
# Parse the URL using Addressable::URI which handles more complex URIs
|
|
24
24
|
parsed_url = Addressable::URI.parse(document.viewer_endpoint)
|
|
25
25
|
|
|
26
|
-
puts "Parsed URL: #{parsed_url.inspect}"
|
|
27
|
-
|
|
28
26
|
# Build a hash to store the extracted components
|
|
29
27
|
parsed_data = {
|
|
30
28
|
base_url: "#{parsed_url.scheme}://#{parsed_url.host}#{parsed_url.port ? ":" + parsed_url.port.to_s : ""}",
|
|
31
29
|
path_pattern: parsed_url.path
|
|
32
30
|
}
|
|
33
31
|
|
|
34
|
-
puts "Parsed Data: #{parsed_data.inspect}"
|
|
35
|
-
|
|
36
32
|
endpoint = parsed_data[:base_url]
|
|
37
33
|
"#{endpoint}/geoserver/wms/reflect?" \
|
|
38
34
|
"&FORMAT=image%2Fpng" \
|
|
@@ -191,7 +191,7 @@ module GeoblacklightAdmin
|
|
|
191
191
|
|
|
192
192
|
# Retreives a url to a static thumbnail from the document's dct_references field, if it exists.
|
|
193
193
|
def image_reference
|
|
194
|
-
@document.
|
|
194
|
+
@document.distributions["http://schema.org/thumbnailUrl"]
|
|
195
195
|
end
|
|
196
196
|
|
|
197
197
|
# Default image size.
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
module GeoblacklightAdmin
|
|
4
4
|
class ItemViewer
|
|
5
|
-
def initialize(
|
|
6
|
-
@
|
|
7
|
-
@keys =
|
|
5
|
+
def initialize(distributions)
|
|
6
|
+
@distributions = distributions
|
|
7
|
+
@keys = distributions.keys.collect { |k| reference_uri_2_key(k) }
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def viewer_protocol
|
|
@@ -12,7 +12,7 @@ module GeoblacklightAdmin
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def viewer_endpoint
|
|
15
|
-
@
|
|
15
|
+
@distributions[viewer_protocol_2_endpoint]
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def reference_uri_2_key(value)
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
<% if @bulk_action.state_machine.current_state == 'created' %>
|
|
44
44
|
<%= form_tag run_admin_bulk_action_path(@bulk_action), method: :patch do -%>
|
|
45
45
|
<%= hidden_field_tag :run, true -%>
|
|
46
|
-
<%= submit_tag 'Run Bulk Action' -%>
|
|
46
|
+
<%= submit_tag '+ Run Bulk Action', class: 'btn btn-primary btn-block' -%>
|
|
47
47
|
<%- end -%>
|
|
48
48
|
<% else %>
|
|
49
49
|
<%= @bulk_action.state_machine.current_state %>
|
|
@@ -15,7 +15,11 @@
|
|
|
15
15
|
<h2 class='h3'>Import for Multiple Documents</h2>
|
|
16
16
|
<% end %>
|
|
17
17
|
|
|
18
|
-
<
|
|
18
|
+
<p class="alert alert-info" role="alert">
|
|
19
|
+
<strong>Note:</strong> New Institutional Access URLs will be created. Existing Institutional Access URLs will be updated per the CSV file.
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
<h3 class='h4'>Upload a CSV File</h3>
|
|
19
23
|
<%= simple_form_for DocumentAccess.new, url: import_admin_document_accesses_path, method: :post, multipart: true do |f| %>
|
|
20
24
|
<div class="form-inputs">
|
|
21
25
|
<%= f.simple_fields_for :assets do |asset_fields| %>
|
|
@@ -24,7 +28,7 @@
|
|
|
24
28
|
</div>
|
|
25
29
|
|
|
26
30
|
<div class="form-actions">
|
|
27
|
-
<%= submit_tag "Import CSV", {class: 'btn btn-primary'} %>
|
|
31
|
+
<%= submit_tag "+ Import CSV", {class: 'btn btn-primary'} %>
|
|
28
32
|
</div>
|
|
29
33
|
<% end %>
|
|
30
34
|
</div>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<div class="table-responsive">
|
|
2
|
+
<table class="table table-striped table-bordered sortable">
|
|
3
|
+
<thead class="thead-dark">
|
|
4
|
+
<tr>
|
|
5
|
+
<th>Thumbnail</th>
|
|
6
|
+
<th>Preview</th>
|
|
7
|
+
<th>Title</th>
|
|
8
|
+
<th>Label</th>
|
|
9
|
+
<th>MimeType</th>
|
|
10
|
+
<th>Reference URI Type</th>
|
|
11
|
+
<th colspan="2">Actions</th>
|
|
12
|
+
</tr>
|
|
13
|
+
</thead>
|
|
14
|
+
<tbody>
|
|
15
|
+
<% document_assets.each do |document_asset| %>
|
|
16
|
+
<tr>
|
|
17
|
+
<td>
|
|
18
|
+
<%= form_with model: document_asset, url: admin_document_document_asset_path(document_asset.parent, document_asset), method: :put, remote: true, class: 'thumbnail-form' do |f| %>
|
|
19
|
+
<%= f.check_box :thumbnail, class: 'thumbnail-toggle', onchange: "this.form.submit()" %>
|
|
20
|
+
<%= f.submit 'Save', class: 'btn btn-sm btn-primary d-none' %>
|
|
21
|
+
<% end %>
|
|
22
|
+
</td>
|
|
23
|
+
<td>
|
|
24
|
+
<% if document_asset.respond_to?(:thumbnail) %>
|
|
25
|
+
<% unless document_asset.file_url(:thumb_standard).nil? %>
|
|
26
|
+
<%= image_tag(document_asset.file_url(:thumb_standard), { height: 100 }) %>
|
|
27
|
+
<% end %>
|
|
28
|
+
<% end %>
|
|
29
|
+
</td>
|
|
30
|
+
<td><%= link_to(document_asset.title, document_asset.file.url) %></td>
|
|
31
|
+
<td><%= document_asset.label %></td>
|
|
32
|
+
<td>
|
|
33
|
+
<%= document_asset.file_data["metadata"]["mime_type"] %>
|
|
34
|
+
<span class="sr-only"><%= document_asset.inspect %></span>
|
|
35
|
+
</td>
|
|
36
|
+
<td>
|
|
37
|
+
<%= document_asset.dct_references_uri_key %>
|
|
38
|
+
</td>
|
|
39
|
+
<td>
|
|
40
|
+
<%= link_to 'Edit', edit_admin_document_document_asset_path(document_asset.parent, document_asset) %>
|
|
41
|
+
</td>
|
|
42
|
+
<td>
|
|
43
|
+
<%= link_to 'Destroy', admin_document_document_asset_path(document_asset.parent, document_asset), method: :delete, data: { confirm: 'Are you sure?' } %>
|
|
44
|
+
</td>
|
|
45
|
+
</tr>
|
|
46
|
+
<% end %>
|
|
47
|
+
</tbody>
|
|
48
|
+
</table>
|
|
49
|
+
</div>
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
<%= @document_asset.class %>
|
|
2
|
-
|
|
3
1
|
<%= simple_form_for [:admin, @document, @document_asset], :url => admin_document_document_asset_path(@document, @document_asset) do |f| %>
|
|
4
2
|
<%= f.error_notification %>
|
|
5
3
|
<%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
|
|
6
4
|
|
|
7
5
|
<div class="form-inputs">
|
|
8
|
-
<%=
|
|
6
|
+
<%= link_to "Parent Document", admin_document_path(@document_asset.parent) %>
|
|
7
|
+
<%= f.input :parent_id, as: :hidden %>
|
|
9
8
|
<%= f.input :title %>
|
|
10
9
|
<%= f.input :label %>
|
|
11
10
|
<%= f.input :dct_references_uri_key, collection: I18n.t("activemodel.enum_values.document/reference.category").invert.sort.insert(0, ["Choose Reference Type", nil]), label: 'Reference' %>
|
|
@@ -30,53 +30,7 @@
|
|
|
30
30
|
</h6>
|
|
31
31
|
<% end %>
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
<table class="table table-striped table-bordered sortable">
|
|
35
|
-
<thead class="thead-dark">
|
|
36
|
-
<tr>
|
|
37
|
-
<th>Thumbnail</th>
|
|
38
|
-
<th>Preview</th>
|
|
39
|
-
<th>Title</th>
|
|
40
|
-
<th>Label</th>
|
|
41
|
-
<th>MimeType</th>
|
|
42
|
-
<th>Reference URI Type</th>
|
|
43
|
-
<th colspan="2">Actions</th>
|
|
44
|
-
</tr>
|
|
45
|
-
</thead>
|
|
46
|
-
<tbody>
|
|
47
|
-
<% @document_assets.each do |document_asset| %>
|
|
48
|
-
<tr>
|
|
49
|
-
<td>
|
|
50
|
-
<% if document_asset.respond_to?(:thumbnail) %>
|
|
51
|
-
<%= document_asset.thumbnail %>
|
|
52
|
-
<% end %>
|
|
53
|
-
</td>
|
|
54
|
-
<td>
|
|
55
|
-
<% if document_asset.respond_to?(:thumbnail) %>
|
|
56
|
-
<% unless document_asset.file_url(:thumb_standard).nil? %>
|
|
57
|
-
<%= image_tag(document_asset.file_url(:thumb_standard), { height: 100 }) %>
|
|
58
|
-
<% end %>
|
|
59
|
-
<% end %>
|
|
60
|
-
</td>
|
|
61
|
-
<td><%= link_to(document_asset.title, document_asset.file.url) %></td>
|
|
62
|
-
<td><%= document_asset.label %></td>
|
|
63
|
-
<td>
|
|
64
|
-
<%= document_asset.file_data["metadata"]["mime_type"] %>
|
|
65
|
-
<span class="sr-only"><%= document_asset.inspect %></span>
|
|
66
|
-
</td>
|
|
67
|
-
<td>
|
|
68
|
-
<%= document_asset.dct_references_uri_key %>
|
|
69
|
-
</td>
|
|
70
|
-
<td>
|
|
71
|
-
<%= link_to 'Edit', edit_admin_document_document_asset_path(document_asset.parent, document_asset) %>
|
|
72
|
-
</td>
|
|
73
|
-
<td>
|
|
74
|
-
<%= link_to 'Destroy', admin_document_document_asset_path(document_asset.parent, document_asset), method: :delete, data: { confirm: 'Are you sure?' } %>
|
|
75
|
-
</td>
|
|
76
|
-
</tr>
|
|
77
|
-
<% end %>
|
|
78
|
-
</tbody>
|
|
79
|
-
</table>
|
|
33
|
+
<%= render partial: 'assets_table', locals: { document_assets: @document_assets } %>
|
|
80
34
|
|
|
81
35
|
<% if @pagy %>
|
|
82
36
|
<h6>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<%- @page_title = "GBL♦Admin - Document - Distribution - #{document_distribution.url}" %>
|
|
2
|
+
|
|
3
|
+
<h1>Distribution</h1>
|
|
4
|
+
|
|
5
|
+
<div class="row">
|
|
6
|
+
<div class="col-9">
|
|
7
|
+
<h2>
|
|
8
|
+
<%= document_distribution.url %>
|
|
9
|
+
<span class="float-right">
|
|
10
|
+
<%= link_to '~ Edit Distribution', edit_admin_document_document_distribution_path(@document, document_distribution), { class: 'btn btn-primary' } %>
|
|
11
|
+
<%= button_to "Destroy this distribution", admin_document_document_distribution_path(@document, document_distribution), method: :delete, class: "btn btn-danger" %>
|
|
12
|
+
</span>
|
|
13
|
+
</h2>
|
|
14
|
+
|
|
15
|
+
<table class="table table-bordered">
|
|
16
|
+
<thead class="thead-dark">
|
|
17
|
+
<tr>
|
|
18
|
+
<th class="header" style="width:300px;">Attribute</th>
|
|
19
|
+
<th class="header">Value</th>
|
|
20
|
+
</tr>
|
|
21
|
+
</thead>
|
|
22
|
+
<tr>
|
|
23
|
+
<th>Reference Type</th>
|
|
24
|
+
<td><%= document_distribution.reference_type.reference_type %></td>
|
|
25
|
+
</tr>
|
|
26
|
+
<tr>
|
|
27
|
+
<th>Reference URL</th>
|
|
28
|
+
<td><%= document_distribution.url %></td>
|
|
29
|
+
</tr>
|
|
30
|
+
<tr>
|
|
31
|
+
<th>Label</th>
|
|
32
|
+
<td><%= document_distribution.label %></td>
|
|
33
|
+
</tr>
|
|
34
|
+
</table>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<%= link_to 'Edit', edit_admin_document_document_distribution_path(@document, document_distribution) %> |
|
|
39
|
+
<%= link_to 'Back', admin_document_document_distributions_path(@document) %>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<%= simple_form_for([:admin, @document, @document_distribution]) do |f| %>
|
|
2
|
+
<%= f.error_notification %>
|
|
3
|
+
<%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
|
|
4
|
+
|
|
5
|
+
<div class="form-inputs">
|
|
6
|
+
<%= f.input :friendlier_id, input_html: { value: @document.friendlier_id, readonly: true } %>
|
|
7
|
+
<%= f.input :reference_type_id, as: :select, collection: ReferenceType.all.map { |r| [r.reference_type, r.id] }, label: 'Reference Type' %>
|
|
8
|
+
<%= f.input :url, label: 'Distribution URL' %>
|
|
9
|
+
<%= f.input :label, autofocus: true, input_html: { disabled: true, id: 'label-input' } %>
|
|
10
|
+
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<div class="form-actions">
|
|
14
|
+
<%= f.button :submit, 'Create Download URL', {class: 'btn btn-primary'} %>
|
|
15
|
+
</div>
|
|
16
|
+
<% end %>
|
|
17
|
+
|
|
18
|
+
<script>
|
|
19
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
20
|
+
const distributionSelect = document.querySelector('select[name="document_distribution[reference_type_id]"]');
|
|
21
|
+
const labelInput = document.getElementById('label-input');
|
|
22
|
+
|
|
23
|
+
function toggleLabelInput() {
|
|
24
|
+
if (distributionSelect.options[distributionSelect.selectedIndex].text === 'Download file') {
|
|
25
|
+
labelInput.disabled = false;
|
|
26
|
+
} else {
|
|
27
|
+
labelInput.disabled = true;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
distributionSelect.addEventListener('change', toggleLabelInput);
|
|
32
|
+
toggleLabelInput(); // Initial check
|
|
33
|
+
});
|
|
34
|
+
</script>
|