geoblacklight_admin 0.5.0 → 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 +24 -11
- 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 +7 -1
- data/app/controllers/admin/assets_controller.rb +47 -32
- data/app/controllers/admin/bookmarks_controller.rb +17 -5
- data/app/controllers/admin/bulk_actions_controller.rb +32 -1
- data/app/controllers/admin/document_accesses_controller.rb +38 -0
- data/app/controllers/admin/document_assets_controller.rb +47 -89
- data/app/controllers/admin/document_distributions_controller.rb +172 -0
- data/app/controllers/admin/documents_controller.rb +43 -57
- data/app/controllers/admin/elements_controller.rb +24 -0
- data/app/controllers/admin/form_elements_controller.rb +33 -0
- data/app/controllers/admin/ids_controller.rb +6 -0
- data/app/controllers/admin/import_documents_controller.rb +11 -1
- data/app/controllers/admin/imports_controller.rb +34 -4
- 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 +10 -1
- 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/bulk_action_revert_document_job.rb +4 -12
- data/app/jobs/bulk_action_run_document_job.rb +2 -10
- 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/jobs/import_document_job.rb +1 -4
- data/app/jobs/import_run_job.rb +1 -1
- data/app/models/admin/bookmark.rb +1 -1
- data/app/models/asset.rb +20 -0
- data/app/models/bulk_action.rb +2 -1
- data/app/models/bulk_actions/change_publication_state.rb +0 -25
- data/app/models/bulk_actions/delete_thumbnails.rb +6 -0
- data/app/models/bulk_actions/draft_document.rb +6 -0
- data/app/models/bulk_actions/harvest_thumbnails.rb +6 -0
- data/app/models/bulk_actions/publish_document.rb +6 -0
- data/app/models/bulk_actions/unpublish_document.rb +6 -0
- data/app/models/document/geom_validator.rb +8 -0
- data/app/models/document/reference.rb +65 -65
- data/app/models/document.rb +129 -72
- 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/csv_duplicates_validator.rb +2 -0
- data/app/models/import/csv_header_validator.rb +3 -1
- data/app/models/import_btaa_aardvark.rb +2 -2
- data/app/models/import_document_state_machine.rb +1 -0
- data/app/models/import_gblv1.rb +2 -2
- 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/iiif_manifest.rb +39 -43
- data/app/services/geoblacklight_admin/image_service/tms.rb +0 -8
- data/app/services/geoblacklight_admin/image_service.rb +1 -1
- data/app/services/geoblacklight_admin/item_viewer.rb +4 -4
- data/app/views/admin/bookmarks/index.html.erb +19 -14
- 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/mappings/index.html.erb +1 -1
- data/app/views/admin/notifications/_notification.html.haml +29 -28
- 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 +53 -12
- data/lib/generators/geoblacklight_admin/install_generator.rb +8 -0
- data/lib/generators/geoblacklight_admin/templates/btaa_sample_records.csv +5 -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/rake_task.rb +2 -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 +137 -53
- data/app/helpers/import_documents_helper.rb +0 -5
- 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
|
@@ -1,14 +1,28 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# Admin::NotificationsController
|
|
4
|
+
#
|
|
5
|
+
# This controller manages the notifications for the admin panel. It provides
|
|
6
|
+
# actions to list, update, destroy, and batch update notifications.
|
|
4
7
|
module Admin
|
|
5
8
|
class NotificationsController < Admin::AdminController
|
|
6
9
|
before_action :set_notification, only: %i[update destroy]
|
|
7
10
|
|
|
11
|
+
# GET /admin/notifications
|
|
12
|
+
#
|
|
13
|
+
# Lists all notifications for the current user, paginated.
|
|
14
|
+
#
|
|
15
|
+
# @return [void]
|
|
8
16
|
def index
|
|
9
17
|
@pagy, @notifications = pagy(current_user.notifications.order(created_at: :desc), items: 20)
|
|
10
18
|
end
|
|
11
19
|
|
|
20
|
+
# PATCH/PUT /admin/notifications/:id
|
|
21
|
+
#
|
|
22
|
+
# Updates the read status of a notification.
|
|
23
|
+
#
|
|
24
|
+
# @param [String] read The read status, "0" for unread, "1" for read.
|
|
25
|
+
# @return [void]
|
|
12
26
|
def update
|
|
13
27
|
case params[:read]
|
|
14
28
|
when "0"
|
|
@@ -25,6 +39,11 @@ module Admin
|
|
|
25
39
|
end
|
|
26
40
|
end
|
|
27
41
|
|
|
42
|
+
# DELETE /admin/notifications/:id
|
|
43
|
+
#
|
|
44
|
+
# Destroys a notification and purges its associated file.
|
|
45
|
+
#
|
|
46
|
+
# @return [void]
|
|
28
47
|
def destroy
|
|
29
48
|
@notification.file.purge
|
|
30
49
|
@notification.destroy
|
|
@@ -34,6 +53,11 @@ module Admin
|
|
|
34
53
|
end
|
|
35
54
|
end
|
|
36
55
|
|
|
56
|
+
# POST /admin/notifications/batch
|
|
57
|
+
#
|
|
58
|
+
# Marks all notifications as read.
|
|
59
|
+
#
|
|
60
|
+
# @return [void]
|
|
37
61
|
def batch
|
|
38
62
|
return unless params[:read] == "all"
|
|
39
63
|
|
|
@@ -44,6 +68,9 @@ module Admin
|
|
|
44
68
|
|
|
45
69
|
private
|
|
46
70
|
|
|
71
|
+
# Sets the notification based on the provided ID.
|
|
72
|
+
#
|
|
73
|
+
# @return [void]
|
|
47
74
|
def set_notification
|
|
48
75
|
@notification = Notification.find(params[:id])
|
|
49
76
|
end
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Admin::ReferenceTypesController
|
|
4
|
+
#
|
|
5
|
+
# This controller manages the CRUD operations for ReferenceType objects
|
|
6
|
+
# within the admin namespace. It includes actions to list, show, create,
|
|
7
|
+
# update, and destroy reference types, as well as a custom sort action.
|
|
8
|
+
class Admin::ReferenceTypesController < Admin::AdminController
|
|
9
|
+
before_action :set_reference_type, only: %i[show edit update destroy]
|
|
10
|
+
|
|
11
|
+
# GET /admin/reference_types or /admin/reference_types.json
|
|
12
|
+
#
|
|
13
|
+
# Lists all reference types.
|
|
14
|
+
def index
|
|
15
|
+
@reference_types = ReferenceType.all
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# GET /admin/reference_types/1 or /admin/reference_types/1.json
|
|
19
|
+
#
|
|
20
|
+
# Shows a specific reference type.
|
|
21
|
+
def show
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# GET /admin/reference_types/new
|
|
25
|
+
#
|
|
26
|
+
# Initializes a new reference type.
|
|
27
|
+
def new
|
|
28
|
+
@reference_type = ReferenceType.new
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# GET /admin/reference_types/1/edit
|
|
32
|
+
#
|
|
33
|
+
# Edits an existing reference type.
|
|
34
|
+
def edit
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# POST /admin/reference_types or /admin/reference_types.json
|
|
38
|
+
#
|
|
39
|
+
# Creates a new reference type. If successful, redirects to the show page
|
|
40
|
+
# of the newly created reference type. Otherwise, re-renders the new form.
|
|
41
|
+
def create
|
|
42
|
+
@reference_type = ReferenceType.new(reference_type_params)
|
|
43
|
+
|
|
44
|
+
respond_to do |format|
|
|
45
|
+
if @reference_type.save
|
|
46
|
+
format.html { redirect_to admin_reference_type_path(@reference_type), notice: "Reference type was successfully created." }
|
|
47
|
+
format.json { render :show, status: :created, location: @reference_type }
|
|
48
|
+
else
|
|
49
|
+
format.html { render :new, status: :unprocessable_entity }
|
|
50
|
+
format.json { render json: @reference_type.errors, status: :unprocessable_entity }
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# PATCH/PUT /admin/reference_types/1 or /admin/reference_types/1.json
|
|
56
|
+
#
|
|
57
|
+
# Updates an existing reference type. If successful, redirects to the show
|
|
58
|
+
# page of the updated reference type. Otherwise, re-renders the edit form.
|
|
59
|
+
def update
|
|
60
|
+
respond_to do |format|
|
|
61
|
+
if @reference_type.update(reference_type_params)
|
|
62
|
+
format.html { redirect_to admin_reference_type_path(@reference_type), notice: "Reference type was successfully updated." }
|
|
63
|
+
format.json { render :show, status: :ok, location: @reference_type }
|
|
64
|
+
else
|
|
65
|
+
format.html { render :edit, status: :unprocessable_entity }
|
|
66
|
+
format.json { render json: @reference_type.errors, status: :unprocessable_entity }
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# DELETE /admin/reference_types/1 or /admin/reference_types/1.json
|
|
72
|
+
#
|
|
73
|
+
# Destroys a reference type. Redirects to the index page with a notice.
|
|
74
|
+
def destroy
|
|
75
|
+
@reference_type.destroy!
|
|
76
|
+
|
|
77
|
+
respond_to do |format|
|
|
78
|
+
format.html { redirect_to admin_reference_types_path, status: :see_other, notice: "Reference type was successfully destroyed." }
|
|
79
|
+
format.json { head :no_content }
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# POST /admin/reference_types/sort
|
|
84
|
+
#
|
|
85
|
+
# Sorts reference types based on the provided list of IDs.
|
|
86
|
+
def sort
|
|
87
|
+
ReferenceType.sort_elements(params[:id_list])
|
|
88
|
+
render body: nil
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
private
|
|
92
|
+
|
|
93
|
+
# Use callbacks to share common setup or constraints between actions.
|
|
94
|
+
#
|
|
95
|
+
# Sets the @reference_type instance variable for actions that require it.
|
|
96
|
+
def set_reference_type
|
|
97
|
+
@reference_type = ReferenceType.find(params[:id])
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Only allow a list of trusted parameters through.
|
|
101
|
+
#
|
|
102
|
+
# Permits the parameters required for creating or updating a reference type.
|
|
103
|
+
def reference_type_params
|
|
104
|
+
params.require(:reference_type).permit(:name, :reference_type, :reference_uri, :label, :note, :position)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# Admin::SearchController
|
|
4
|
+
# This controller handles search-related actions for the admin interface.
|
|
4
5
|
module Admin
|
|
5
6
|
class SearchController < Admin::AdminController
|
|
7
|
+
# GET /admin/search
|
|
8
|
+
#
|
|
9
|
+
# This action sets up the request URL and retrieves facet options
|
|
10
|
+
# from the Blacklight API.
|
|
11
|
+
#
|
|
12
|
+
# @return [void]
|
|
6
13
|
def index
|
|
7
14
|
@request = "#{request.protocol}#{request.host}:#{request.port}"
|
|
8
15
|
@facet_options = BlacklightApiFacets.new(@request).facets
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# Admin::UsersController
|
|
4
|
+
#
|
|
5
|
+
# This controller handles the actions related to admin users.
|
|
6
|
+
# It inherits from Admin::AdminController, which provides
|
|
7
|
+
# common functionality for all admin-related controllers.
|
|
4
8
|
module Admin
|
|
5
9
|
class UsersController < Admin::AdminController
|
|
10
|
+
# GET /admin/users
|
|
11
|
+
#
|
|
12
|
+
# This action retrieves all users with admin privileges.
|
|
13
|
+
# It assigns the result to the @users instance variable,
|
|
14
|
+
# which can be used in the corresponding view to display
|
|
15
|
+
# the list of admin users.
|
|
6
16
|
def index
|
|
7
17
|
@users = User.where(admin: true)
|
|
8
18
|
end
|
data/app/helpers/asset_helper.rb
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# AssetHelper
|
|
4
|
+
#
|
|
5
|
+
# This module provides helper methods for asset management.
|
|
4
6
|
module AssetHelper
|
|
7
|
+
# Determines if an asset has a thumbnail to render.
|
|
8
|
+
#
|
|
9
|
+
# @param asset [Object] The asset object to check.
|
|
10
|
+
# @return [Boolean] Returns true if the asset has a file URL and file derivatives present, otherwise false.
|
|
5
11
|
def asset_thumb_to_render?(asset)
|
|
6
12
|
asset&.file_url&.present? && asset&.file_derivatives&.present?
|
|
7
13
|
end
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# BulkActionsHelper
|
|
4
|
+
#
|
|
5
|
+
# This module provides helper methods for handling bulk actions
|
|
6
|
+
# within the GeoblacklightAdmin application.
|
|
4
7
|
module BulkActionsHelper
|
|
8
|
+
# Returns a collection of attributes that can be used for bulk actions.
|
|
9
|
+
#
|
|
10
|
+
# The collection includes all importable fields from the GeoblacklightAdmin
|
|
11
|
+
# schema, with "Publication State" prepended to the list.
|
|
12
|
+
#
|
|
13
|
+
# @return [Array<String>] an array of attribute names
|
|
5
14
|
def bulk_actions_collection
|
|
6
|
-
attrs =
|
|
15
|
+
attrs = GeoblacklightAdmin::Schema.instance.importable_fields.collect { |key, _value| key }
|
|
7
16
|
attrs.prepend("Publication State")
|
|
8
17
|
end
|
|
9
18
|
end
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# DocumentHelper
|
|
4
|
+
#
|
|
5
|
+
# This module provides helper methods for handling document-related
|
|
6
|
+
# functionalities such as generating publication state badges, creating
|
|
7
|
+
# localized links, and handling pagination links.
|
|
4
8
|
module DocumentHelper
|
|
9
|
+
# Generates a badge for the publication state of a document.
|
|
10
|
+
#
|
|
11
|
+
# @param document [Object] the document object containing the publication state
|
|
12
|
+
# @return [String] HTML link with a span element representing the publication state
|
|
5
13
|
def publication_state_badge(document)
|
|
6
14
|
case document.publication_state
|
|
7
15
|
when "draft"
|
|
@@ -19,15 +27,27 @@ module DocumentHelper
|
|
|
19
27
|
end
|
|
20
28
|
end
|
|
21
29
|
|
|
30
|
+
# Localizes a given link by parsing its URI and appending it to a base path.
|
|
31
|
+
#
|
|
32
|
+
# @param link [String] the link to be localized
|
|
33
|
+
# @return [String] the localized link
|
|
22
34
|
def localize_link(link)
|
|
23
35
|
uri = URI.parse(link)
|
|
24
36
|
"/admin/documents?#{uri.query}"
|
|
25
37
|
end
|
|
26
38
|
|
|
39
|
+
# Creates a sort link with a label and localized URL.
|
|
40
|
+
#
|
|
41
|
+
# @param link [Hash] a hash containing link attributes and self link
|
|
42
|
+
# @return [String] HTML link element for sorting
|
|
27
43
|
def sort_link(link)
|
|
28
44
|
link_to link["attributes"]["label"], localize_link(link["links"]["self"]), {class: "dropdown-item"}
|
|
29
45
|
end
|
|
30
46
|
|
|
47
|
+
# Processes a link from an API response, determining whether to add or remove a facet.
|
|
48
|
+
#
|
|
49
|
+
# @param link [Hash] a hash containing links for adding or removing facets
|
|
50
|
+
# @return [Hash] a hash with action and link keys
|
|
31
51
|
def link_from_api(link)
|
|
32
52
|
# Append facet - Full URI returned
|
|
33
53
|
uri = URI.parse(link["links"]["self"])
|
|
@@ -38,6 +58,10 @@ module DocumentHelper
|
|
|
38
58
|
{action: "remove", link: "/admin/documents?#{uri.query}"}
|
|
39
59
|
end
|
|
40
60
|
|
|
61
|
+
# Generates a link to the previous page in a paginated list.
|
|
62
|
+
#
|
|
63
|
+
# @param links [Hash] a hash containing pagination links
|
|
64
|
+
# @return [String] HTML link element for the previous page
|
|
41
65
|
def previous_link(links)
|
|
42
66
|
if links["prev"]
|
|
43
67
|
link_to "Previous", localize_link(links["prev"]), {class: "btn btn-outline-primary btn-sm"}
|
|
@@ -46,6 +70,10 @@ module DocumentHelper
|
|
|
46
70
|
end
|
|
47
71
|
end
|
|
48
72
|
|
|
73
|
+
# Generates a link to the next page in a paginated list.
|
|
74
|
+
#
|
|
75
|
+
# @param links [Hash] a hash containing pagination links
|
|
76
|
+
# @return [String] HTML link element for the next page
|
|
49
77
|
def next_link(links)
|
|
50
78
|
if links["next"]
|
|
51
79
|
link_to "Next", localize_link(links["next"]), {class: "btn btn-outline-primary btn-sm"}
|
|
@@ -54,10 +82,18 @@ module DocumentHelper
|
|
|
54
82
|
end
|
|
55
83
|
end
|
|
56
84
|
|
|
85
|
+
# Constructs a link to a document's page in the Blacklight catalog.
|
|
86
|
+
#
|
|
87
|
+
# @param document [Object] the document object
|
|
88
|
+
# @return [String] the URL to the document's Blacklight catalog page
|
|
57
89
|
def blacklight_link(document)
|
|
58
90
|
"#{BLACKLIGHT_URL}/catalog/#{document.friendlier_id}"
|
|
59
91
|
end
|
|
60
92
|
|
|
93
|
+
# Determines if a document's thumbnail should be rendered.
|
|
94
|
+
#
|
|
95
|
+
# @param document [Object] the document object
|
|
96
|
+
# @return [Boolean] true if the thumbnail should be rendered, false otherwise
|
|
61
97
|
def thumb_to_render?(document)
|
|
62
98
|
document&.thumbnail&.file_url&.present? && document&.thumbnail&.file_derivatives&.present?
|
|
63
99
|
end
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# GeoblacklightAdminHelper
|
|
4
|
+
#
|
|
5
|
+
# This module provides helper methods for the GeoBlacklight admin interface.
|
|
6
|
+
# It includes methods for handling JSON data, generating paths, formatting
|
|
7
|
+
# flash messages, and more.
|
|
4
8
|
module GeoblacklightAdminHelper
|
|
5
9
|
# @TODO:
|
|
6
10
|
# Cannot generate app if uncommented...
|
|
7
11
|
# Uncomment after app is generated to fix view errors
|
|
8
12
|
include ::Pagy::Frontend if defined?(Pagy)
|
|
9
13
|
|
|
10
|
-
#
|
|
14
|
+
# Removes blank values from JSON data.
|
|
15
|
+
#
|
|
16
|
+
# @param value [String, Array] the value to check for presence
|
|
17
|
+
# @return [String, Array, nil] the original value if present, otherwise nil
|
|
11
18
|
def no_json_blanks(value)
|
|
12
19
|
case value
|
|
13
20
|
when String
|
|
@@ -17,17 +24,21 @@ module GeoblacklightAdminHelper
|
|
|
17
24
|
end
|
|
18
25
|
end
|
|
19
26
|
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
27
|
+
# Generates a search path for the QA (questioning_authority) gem.
|
|
28
|
+
#
|
|
29
|
+
# @param vocab [String] the vocabulary to search
|
|
30
|
+
# @param subauthority [String, nil] the subauthority to search
|
|
31
|
+
# @return [String] the generated search path
|
|
23
32
|
def qa_search_vocab_path(vocab, subauthority = nil)
|
|
24
33
|
path = "/authorities/search/#{CGI.escape vocab}"
|
|
25
|
-
|
|
26
34
|
path += "/#{CGI.escape subauthority}" if subauthority
|
|
27
|
-
|
|
28
35
|
path
|
|
29
36
|
end
|
|
30
37
|
|
|
38
|
+
# Maps flash message levels to CSS classes.
|
|
39
|
+
#
|
|
40
|
+
# @param level [String] the flash message level
|
|
41
|
+
# @return [String] the corresponding CSS class
|
|
31
42
|
def flash_class(level)
|
|
32
43
|
alerts = {
|
|
33
44
|
"notice" => "alert alert-info",
|
|
@@ -38,6 +49,9 @@ module GeoblacklightAdminHelper
|
|
|
38
49
|
alerts[level]
|
|
39
50
|
end
|
|
40
51
|
|
|
52
|
+
# Provides a mapping of institution codes to institution names.
|
|
53
|
+
#
|
|
54
|
+
# @return [Hash] a hash mapping institution codes to names
|
|
41
55
|
def b1g_institution_codes
|
|
42
56
|
{
|
|
43
57
|
"01" => "Indiana University",
|
|
@@ -58,11 +72,17 @@ module GeoblacklightAdminHelper
|
|
|
58
72
|
}
|
|
59
73
|
end
|
|
60
74
|
|
|
75
|
+
# Generates an HTML badge for bookmarks.
|
|
76
|
+
#
|
|
77
|
+
# @return [String] the HTML string for the bookmarks badge
|
|
61
78
|
def bookmarks_badge
|
|
62
79
|
bookmarks_classes = ["badge", "badge-dark"]
|
|
63
80
|
"<span class='#{bookmarks_classes.join(" ")}' id='bookmarks-count'>#{current_user.bookmarks.size}</span>"
|
|
64
81
|
end
|
|
65
82
|
|
|
83
|
+
# Generates an HTML badge for notifications.
|
|
84
|
+
#
|
|
85
|
+
# @return [String] the HTML string for the notifications badge
|
|
66
86
|
def notifications_badge
|
|
67
87
|
notifications_classes = ["badge"]
|
|
68
88
|
notifications_classes << "badge-dark" if current_user.notifications.unread.empty?
|
|
@@ -70,7 +90,10 @@ module GeoblacklightAdminHelper
|
|
|
70
90
|
"<span class='#{notifications_classes.join(" ")}' id='notification-count'>#{current_user.notifications.unread.size}</span>"
|
|
71
91
|
end
|
|
72
92
|
|
|
73
|
-
#
|
|
93
|
+
# Converts parameters into hidden form fields.
|
|
94
|
+
#
|
|
95
|
+
# @param params [Hash] the parameters to convert
|
|
96
|
+
# @return [String] the HTML string of hidden fields
|
|
74
97
|
def params_as_hidden_fields(params)
|
|
75
98
|
hidden_fields = []
|
|
76
99
|
flatten_hash(params).each do |name, value|
|
|
@@ -83,6 +106,12 @@ module GeoblacklightAdminHelper
|
|
|
83
106
|
safe_join(hidden_fields, "\n")
|
|
84
107
|
end
|
|
85
108
|
|
|
109
|
+
# Flattens a nested hash into a single-level hash with keys representing the
|
|
110
|
+
# nested structure.
|
|
111
|
+
#
|
|
112
|
+
# @param hash [Hash] the hash to flatten
|
|
113
|
+
# @param ancestor_names [Array] the ancestor keys for nested hashes
|
|
114
|
+
# @return [Hash] the flattened hash
|
|
86
115
|
def flatten_hash(hash, ancestor_names = [])
|
|
87
116
|
flat_hash = {}
|
|
88
117
|
hash.each do |k, v|
|
|
@@ -100,6 +129,10 @@ module GeoblacklightAdminHelper
|
|
|
100
129
|
flat_hash
|
|
101
130
|
end
|
|
102
131
|
|
|
132
|
+
# Generates a key for a flattened hash from an array of names.
|
|
133
|
+
#
|
|
134
|
+
# @param names [Array] the array of names
|
|
135
|
+
# @return [String] the generated key
|
|
103
136
|
def flat_hash_key(names)
|
|
104
137
|
names = Array.new(names)
|
|
105
138
|
name = names.shift.to_s.dup
|
|
@@ -109,6 +142,10 @@ module GeoblacklightAdminHelper
|
|
|
109
142
|
name
|
|
110
143
|
end
|
|
111
144
|
|
|
145
|
+
# Maps a character to a CSS class for diff highlighting.
|
|
146
|
+
#
|
|
147
|
+
# @param char [String] the character representing a diff operation
|
|
148
|
+
# @return [String] the corresponding CSS class
|
|
112
149
|
def diff_class(char)
|
|
113
150
|
case char
|
|
114
151
|
when "~"
|
|
@@ -122,6 +159,10 @@ module GeoblacklightAdminHelper
|
|
|
122
159
|
end
|
|
123
160
|
end
|
|
124
161
|
|
|
162
|
+
# Generates a link to the admin import page for a given import.
|
|
163
|
+
#
|
|
164
|
+
# @param import [Object] the import object
|
|
165
|
+
# @return [String] the HTML link to the admin import page
|
|
125
166
|
def link_to_admin_import(import)
|
|
126
167
|
path = admin_documents_path(
|
|
127
168
|
{
|
|
@@ -132,6 +173,12 @@ module GeoblacklightAdminHelper
|
|
|
132
173
|
link_to import.name, path
|
|
133
174
|
end
|
|
134
175
|
|
|
176
|
+
# Generates a link to the GeoBlacklight import page with optional state.
|
|
177
|
+
#
|
|
178
|
+
# @param label [String] the link label
|
|
179
|
+
# @param import [Object] the import object
|
|
180
|
+
# @param state [Boolean] the publication state
|
|
181
|
+
# @return [String] the HTML link to the GeoBlacklight import page
|
|
135
182
|
def link_to_gbl_import(label, import, state = false)
|
|
136
183
|
path = if state
|
|
137
184
|
blacklight_path(
|
|
@@ -152,7 +199,40 @@ module GeoblacklightAdminHelper
|
|
|
152
199
|
link_to(label, path)
|
|
153
200
|
end
|
|
154
201
|
|
|
202
|
+
# Generates options for asset DCT references.
|
|
203
|
+
#
|
|
204
|
+
# @return [String] the escaped JavaScript string of options
|
|
155
205
|
def assets_dct_references_options
|
|
156
|
-
escape_javascript(options_for_select(I18n.t("activemodel.
|
|
206
|
+
escape_javascript(options_for_select(I18n.t("activemodel.asset_enum_values.document/reference.category").invert.sort.insert(0, ["Choose Reference Type", nil]))).to_s
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Determines if a document's thumbnail should be rendered.
|
|
210
|
+
#
|
|
211
|
+
# @param document [Object] the document object
|
|
212
|
+
# @return [Boolean] true if the thumbnail should be rendered, false otherwise
|
|
213
|
+
def thumb_to_render?(document)
|
|
214
|
+
if document&.thumbnail&.file_url&.present? && document&.thumbnail&.file_derivatives&.present?
|
|
215
|
+
true
|
|
216
|
+
elsif document&.document_assets&.any?
|
|
217
|
+
document.document_assets.any? do |asset|
|
|
218
|
+
asset.file_derivatives&.key?(:thumb_standard_2X)
|
|
219
|
+
end
|
|
220
|
+
else
|
|
221
|
+
false
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# Returns the URL of the thumbnail to render for a document.
|
|
226
|
+
#
|
|
227
|
+
# @param document [Object] the document object
|
|
228
|
+
# @return [String] the URL of the thumbnail to render
|
|
229
|
+
def thumbnail_to_render(document)
|
|
230
|
+
if document&.thumbnail&.file_url&.present? && document&.thumbnail&.file_derivatives&.present?
|
|
231
|
+
document.thumbnail.file_url(:thumb_standard_2X)
|
|
232
|
+
elsif document&.document_assets&.any?
|
|
233
|
+
document.document_assets.find do |asset|
|
|
234
|
+
asset.file_derivatives&.key?(:thumb_standard_2X)
|
|
235
|
+
end&.file_url(:thumb_standard_2X)
|
|
236
|
+
end
|
|
157
237
|
end
|
|
158
238
|
end
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# MappingsHelper
|
|
4
|
+
#
|
|
5
|
+
# This module provides helper methods for handling mappings in the application.
|
|
6
|
+
# It includes methods to generate attribute collections and provide mapping
|
|
7
|
+
# and delimiter suggestions based on import configurations.
|
|
4
8
|
module MappingsHelper
|
|
9
|
+
# Returns a collection of attributes that can be used for mapping.
|
|
10
|
+
#
|
|
11
|
+
# The collection is generated from importable elements, sorted, and includes
|
|
12
|
+
# additional options for an empty string and "Discard".
|
|
13
|
+
#
|
|
14
|
+
# @return [Array<String>] a sorted array of attribute names with additional options.
|
|
5
15
|
def attribute_collection
|
|
6
16
|
attrs = Element.importable.map(&:solr_field).sort
|
|
7
17
|
attrs.prepend("")
|
|
@@ -9,6 +19,14 @@ module MappingsHelper
|
|
|
9
19
|
attrs
|
|
10
20
|
end
|
|
11
21
|
|
|
22
|
+
# Provides a mapping suggestion for a given header based on the import configuration.
|
|
23
|
+
#
|
|
24
|
+
# Checks if the header is included in the import's mapping configuration and returns
|
|
25
|
+
# the destination if available.
|
|
26
|
+
#
|
|
27
|
+
# @param import [Object] the import object containing mapping configurations.
|
|
28
|
+
# @param header [String] the header for which the mapping suggestion is needed.
|
|
29
|
+
# @return [String, false] the destination mapping if available, otherwise false.
|
|
12
30
|
def mapping_suggestion(import, header)
|
|
13
31
|
if import.mapping_configuration.include?(header.to_sym)
|
|
14
32
|
import.mapping_configuration[header.to_sym][:destination]
|
|
@@ -17,6 +35,14 @@ module MappingsHelper
|
|
|
17
35
|
end
|
|
18
36
|
end
|
|
19
37
|
|
|
38
|
+
# Provides a delimiter suggestion for a given header based on the import configuration.
|
|
39
|
+
#
|
|
40
|
+
# Checks if the header is included in the import's mapping configuration and returns
|
|
41
|
+
# the delimiter if available.
|
|
42
|
+
#
|
|
43
|
+
# @param import [Object] the import object containing mapping configurations.
|
|
44
|
+
# @param header [String] the header for which the delimiter suggestion is needed.
|
|
45
|
+
# @return [String, false] the delimiter if available, otherwise false.
|
|
20
46
|
def delimiter_suggestion(import, header)
|
|
21
47
|
if import.mapping_configuration.include?(header.to_sym)
|
|
22
48
|
import.mapping_configuration[header.to_sym][:delimited]
|
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# Solr indexing for our document class. Still a work in progress.
|
|
4
|
+
#
|
|
5
|
+
# The DocumentIndexer class is responsible for configuring how documents
|
|
6
|
+
# are indexed into Solr. It uses the Kithe::Indexer framework to map
|
|
7
|
+
# document attributes to Solr fields.
|
|
8
|
+
#
|
|
9
|
+
# The configuration block defines various fields that are indexed, including
|
|
10
|
+
# fields specific to GeoBlacklight and custom fields defined via the Element model.
|
|
11
|
+
#
|
|
12
|
+
# Fields:
|
|
13
|
+
# - model_pk_ssi: The primary key of the model, extracted from the object's ID.
|
|
14
|
+
# - gbl_mdVersion_s: A static version string for GeoBlacklight.
|
|
15
|
+
# - gbl_mdModified_dt: The modification date of the metadata.
|
|
16
|
+
# - date_created_dtsi: The creation date of the record, in UTC ISO8601 format.
|
|
17
|
+
# - date_modified_dtsi: The last modification date of the record, in UTC ISO8601 format.
|
|
18
|
+
# - b1g_geom_import_id_ssi: The import ID for GeoBlacklight administration.
|
|
19
|
+
#
|
|
20
|
+
# If the "elements" table exists, additional fields are indexed based on
|
|
21
|
+
# the Element model's configuration.
|
|
4
22
|
class DocumentIndexer < Kithe::Indexer
|
|
5
23
|
configure do
|
|
6
24
|
# Kithe
|
|
@@ -12,8 +30,10 @@ class DocumentIndexer < Kithe::Indexer
|
|
|
12
30
|
# to_field 'geomg_id_s', obj_extract('friendlier_id') # the actual db pk, a UUID
|
|
13
31
|
|
|
14
32
|
# Define `to_field`(s) via Element
|
|
15
|
-
|
|
16
|
-
|
|
33
|
+
if ActiveRecord::Base.connection.table_exists?("elements")
|
|
34
|
+
Element.indexable.each do |elm|
|
|
35
|
+
to_field elm.solr_field, obj_extract(elm.index_value)
|
|
36
|
+
end
|
|
17
37
|
end
|
|
18
38
|
|
|
19
39
|
to_field "gbl_mdModified_dt", obj_extract("gbl_mdModified_dt")
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Action Cable provides the framework to deal with WebSockets in Rails.
|
|
2
|
+
// You can generate new channels where WebSocket features live using the `bin/rails generate channel` command.
|
|
3
|
+
|
|
4
|
+
import { createConsumer } from "@rails/actioncable"
|
|
5
|
+
|
|
6
|
+
export default createConsumer()
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import consumer from "./consumer"
|
|
2
|
+
|
|
3
|
+
consumer.subscriptions.create({ channel: "ExportChannel" }, {
|
|
4
|
+
connected() {
|
|
5
|
+
// Called when the subscription is ready for use on the server
|
|
6
|
+
console.log("GBL Admin - ExportChannel connected");
|
|
7
|
+
},
|
|
8
|
+
|
|
9
|
+
disconnected() {
|
|
10
|
+
// Called when the subscription has been terminated by the server
|
|
11
|
+
console.log("GBL Admin - ExportChannel disconnected");
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
received(data) {
|
|
15
|
+
console.log('GBL Admin - ExportChannel received!');
|
|
16
|
+
console.log(data);
|
|
17
|
+
|
|
18
|
+
if (data['progress']) {
|
|
19
|
+
console.log(data['progress']);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (data['actions']) {
|
|
23
|
+
for (let index = 0; index < data.actions.length; ++index) {
|
|
24
|
+
var fnstring = data.actions[index].method;
|
|
25
|
+
var fn = window["GBLADMIN"][fnstring];
|
|
26
|
+
if (typeof fn === "function") fn(data.actions[index].payload);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
});
|
|
@@ -12,6 +12,7 @@ import { Controller } from "stimulus"
|
|
|
12
12
|
export default class extends Controller {
|
|
13
13
|
|
|
14
14
|
connect() {
|
|
15
|
+
console.log("GBL Admin - ResultsController connected");
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
checkedState(checked, selector='input[type=checkbox]') {
|
|
@@ -228,6 +229,7 @@ export default class extends Controller {
|
|
|
228
229
|
}
|
|
229
230
|
|
|
230
231
|
exportCsvDocumentDownloads() {
|
|
232
|
+
console.log('Export - CsvDocumentDownloads')
|
|
231
233
|
var scope = this.checkSelectionScope();
|
|
232
234
|
var el = document.querySelector('#result-selected-options');
|
|
233
235
|
if(scope === 'pageset') {
|
|
@@ -238,6 +240,7 @@ export default class extends Controller {
|
|
|
238
240
|
}
|
|
239
241
|
|
|
240
242
|
exportCsvDocumentAccessLinks() {
|
|
243
|
+
console.log('Export - CsvDocumentAccessLinks')
|
|
241
244
|
var scope = this.checkSelectionScope();
|
|
242
245
|
var el = document.querySelector('#result-selected-options');
|
|
243
246
|
if(scope === 'pageset') {
|
|
@@ -247,6 +250,17 @@ export default class extends Controller {
|
|
|
247
250
|
}
|
|
248
251
|
}
|
|
249
252
|
|
|
253
|
+
exportCsvDocumentDistributions() {
|
|
254
|
+
console.log('Export - CsvDocumentDistributions')
|
|
255
|
+
var scope = this.checkSelectionScope();
|
|
256
|
+
var el = document.querySelector('#result-selected-options');
|
|
257
|
+
if(scope === 'pageset') {
|
|
258
|
+
window.location = el.dataset.pageset + "&format=csv_document_distributions"
|
|
259
|
+
} else {
|
|
260
|
+
window.location = el.dataset.resultset + "&format=csv_document_distributions"
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
250
264
|
bulkAction() {
|
|
251
265
|
var scope = this.checkSelectionScope();
|
|
252
266
|
var el = document.querySelector('#result-selected-options');
|