geoblacklight_admin 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +18 -9
  3. data/Rakefile +83 -47
  4. data/app/assets/javascripts/geoblacklight_admin/chosen.js +1 -0
  5. data/app/assets/stylesheets/geoblacklight_admin/_core.scss +24 -0
  6. data/app/assets/stylesheets/geoblacklight_admin/modules/_nav.scss +0 -5
  7. data/app/assets/stylesheets/geoblacklight_admin/modules/_tables.scss +1 -1
  8. data/app/controllers/admin/admin_controller.rb +16 -0
  9. data/app/controllers/admin/advanced_search_controller.rb +1 -1
  10. data/app/controllers/admin/assets_controller.rb +41 -5
  11. data/app/controllers/admin/bookmarks_controller.rb +14 -2
  12. data/app/controllers/admin/bulk_actions_controller.rb +31 -0
  13. data/app/controllers/admin/document_accesses_controller.rb +38 -0
  14. data/app/controllers/admin/document_assets_controller.rb +46 -9
  15. data/app/controllers/admin/document_distributions_controller.rb +172 -0
  16. data/app/controllers/admin/documents_controller.rb +41 -55
  17. data/app/controllers/admin/elements_controller.rb +22 -0
  18. data/app/controllers/admin/form_elements_controller.rb +31 -0
  19. data/app/controllers/admin/import_documents_controller.rb +11 -1
  20. data/app/controllers/admin/imports_controller.rb +32 -2
  21. data/app/controllers/admin/mappings_controller.rb +15 -0
  22. data/app/controllers/admin/notifications_controller.rb +27 -0
  23. data/app/controllers/admin/reference_types_controller.rb +106 -0
  24. data/app/controllers/admin/search_controller.rb +7 -0
  25. data/app/controllers/admin/users_controller.rb +10 -0
  26. data/app/helpers/asset_helper.rb +6 -0
  27. data/app/helpers/bulk_actions_helper.rb +9 -0
  28. data/app/helpers/document_helper.rb +36 -0
  29. data/app/helpers/geoblacklight_admin_helper.rb +88 -8
  30. data/app/helpers/mappings_helper.rb +26 -0
  31. data/app/indexers/document_indexer.rb +22 -2
  32. data/app/javascript/channels/consumer.js +6 -0
  33. data/app/javascript/channels/export_channel.js +30 -0
  34. data/app/javascript/channels/index.js +3 -0
  35. data/app/javascript/controllers/results_controller.js +14 -0
  36. data/app/javascript/index.js +8 -2
  37. data/app/jobs/export_job.rb +35 -8
  38. data/app/jobs/geoblacklight_admin/delete_thumbnail_job.rb +19 -0
  39. data/app/jobs/geoblacklight_admin/remove_parent_dct_references_uri_job.rb +16 -0
  40. data/app/jobs/geoblacklight_admin/set_parent_dct_references_uri_job.rb +17 -0
  41. data/app/jobs/geoblacklight_admin/store_image_job.rb +22 -0
  42. data/app/models/asset.rb +20 -0
  43. data/app/models/bulk_action.rb +2 -1
  44. data/app/models/document/geom_validator.rb +8 -0
  45. data/app/models/document/reference.rb +65 -65
  46. data/app/models/document.rb +128 -71
  47. data/app/models/document_distribution.rb +145 -0
  48. data/app/models/element.rb +2 -0
  49. data/app/models/geoblacklight_admin/schema.rb +10 -2
  50. data/app/models/import_document_state_machine.rb +1 -0
  51. data/app/models/reference_type.rb +40 -0
  52. data/app/models/user.rb +4 -2
  53. data/app/services/export_csv_document_distributions_service.rb +61 -0
  54. data/app/services/geoblacklight_admin/image_service/tms.rb +0 -4
  55. data/app/services/geoblacklight_admin/image_service.rb +1 -1
  56. data/app/services/geoblacklight_admin/item_viewer.rb +4 -4
  57. data/app/views/admin/bulk_actions/show.html.erb +1 -1
  58. data/app/views/admin/document_accesses/import.html.erb +6 -2
  59. data/app/views/admin/document_assets/_assets_table.html.erb +49 -0
  60. data/app/views/admin/document_assets/_form.html.erb +2 -3
  61. data/app/views/admin/document_assets/index.html.erb +1 -47
  62. data/app/views/admin/document_distributions/_document_distribution.html.erb +39 -0
  63. data/app/views/admin/document_distributions/_document_distribution.json.jbuilder +2 -0
  64. data/app/views/admin/document_distributions/_form.html.erb +34 -0
  65. data/app/views/admin/document_distributions/destroy_all.html.erb +82 -0
  66. data/app/views/admin/document_distributions/edit.html.erb +12 -0
  67. data/app/views/admin/document_distributions/import.html.erb +80 -0
  68. data/app/views/admin/document_distributions/index.html.erb +143 -0
  69. data/app/views/admin/document_distributions/index.json.jbuilder +1 -0
  70. data/app/views/admin/document_distributions/new.html.erb +11 -0
  71. data/app/views/admin/document_distributions/show.html.erb +10 -0
  72. data/app/views/admin/document_distributions/show.json.jbuilder +1 -0
  73. data/app/views/admin/documents/_document.html.erb +1 -3
  74. data/app/views/admin/documents/_form.html.erb +2 -4
  75. data/app/views/admin/documents/_form_control.html.erb +5 -2
  76. data/app/views/admin/documents/_form_nav.html.erb +14 -5
  77. data/app/views/admin/documents/_form_nav_kithe.html.erb +4 -1
  78. data/app/views/admin/documents/_json_aardvark.jbuilder +1 -1
  79. data/app/views/admin/documents/_json_gbl_v1.jbuilder +1 -1
  80. data/app/views/admin/documents/_result_selected_options.html.erb +5 -2
  81. data/app/views/admin/documents/admin.html.erb +5 -5
  82. data/app/views/admin/documents/features/_document_references.html.erb +23 -0
  83. data/app/views/admin/documents/features/_multiple_download_links.html.erb +29 -26
  84. data/app/views/admin/ids/fetch.json.jbuilder +0 -2
  85. data/app/views/admin/ids/index.json.jbuilder +0 -2
  86. data/app/views/admin/imports/_form.html.erb +1 -1
  87. data/app/views/admin/imports/show.html.erb +1 -1
  88. data/app/views/admin/layouts/application.html.erb +4 -2
  89. data/app/views/admin/reference_types/_form.html.erb +25 -0
  90. data/app/views/admin/reference_types/_reference_type.html.erb +52 -0
  91. data/app/views/admin/reference_types/_reference_type.json.jbuilder +2 -0
  92. data/app/views/admin/reference_types/edit.html.erb +12 -0
  93. data/app/views/admin/reference_types/index.html.erb +52 -0
  94. data/app/views/admin/reference_types/index.json.jbuilder +1 -0
  95. data/app/views/admin/reference_types/new.html.erb +11 -0
  96. data/app/views/admin/reference_types/show.html.erb +3 -0
  97. data/app/views/admin/reference_types/show.json.jbuilder +1 -0
  98. data/app/views/admin/shared/_footer.html.erb +5 -2
  99. data/app/views/admin/shared/_js_behaviors.html.erb +2 -3
  100. data/app/views/admin/shared/_navbar.html.erb +9 -2
  101. data/app/views/admin/users/index.html.erb +0 -1
  102. data/app/views/catalog/_show_gbl_admin.html.erb +1 -1
  103. data/config/initializers/defaults.yml +310 -0
  104. data/config/initializers/rails_config.rb +8 -0
  105. data/config/locales/documents.en.yml +14 -0
  106. data/config/routes.rb +30 -5
  107. data/db/import_references_schema_support.numbers +0 -0
  108. data/db/migrate/20230316183001_add_geoblacklight_admin_gem.rb +0 -12
  109. data/db/migrate/20241009200524_create_admin_reference_types.rb +13 -0
  110. data/db/migrate/20241010161420_create_document_references.rb +14 -0
  111. data/db/migrate/20241120238823_rename_references_to_distributions.rb +5 -0
  112. data/db/seeds.rb +5 -0
  113. data/db/seeds_elements.csv +1 -1
  114. data/db/seeds_elements.numbers +0 -0
  115. data/db/seeds_reference_types.csv +29 -0
  116. data/db/seeds_reference_types.numbers +0 -0
  117. data/db/structure.sql +1 -38
  118. data/lib/compose.yml +31 -0
  119. data/lib/generators/geoblacklight_admin/config_generator.rb +48 -12
  120. data/lib/generators/geoblacklight_admin/install_generator.rb +8 -0
  121. data/lib/generators/geoblacklight_admin/templates/config/database.yml +1 -1
  122. data/lib/generators/geoblacklight_admin/templates/config/initializers/devise.rb +0 -2
  123. data/lib/generators/geoblacklight_admin/templates/config/initializers/mime_types.rb +1 -0
  124. data/lib/generators/geoblacklight_admin/templates/demo-app/Dockerfile +31 -0
  125. data/lib/generators/geoblacklight_admin/templates/demo-app/compose.yml +42 -0
  126. data/lib/generators/geoblacklight_admin/templates/demo-app/start-server.sh +21 -0
  127. data/lib/geoblacklight_admin/engine.rb +4 -0
  128. data/lib/geoblacklight_admin/tasks/distributions.rake +69 -0
  129. data/lib/geoblacklight_admin/tasks/images.rake +1 -0
  130. data/lib/geoblacklight_admin/tasks/solr.rake +31 -0
  131. data/lib/geoblacklight_admin/version.rb +1 -1
  132. data/lib/geoblacklight_admin.rb +4 -0
  133. metadata +78 -41
  134. data/app/javascript/entrypoints/engine.js +0 -8
  135. data/config/locales/devise_invitable.en.yml +0 -31
  136. data/lib/generators/geoblacklight_admin/templates/devise/invitations/edit.html.erb +0 -15
  137. data/lib/generators/geoblacklight_admin/templates/devise/invitations/new.html.erb +0 -15
  138. data/lib/generators/geoblacklight_admin/templates/devise/mailer/invitation_instructions.html.erb +0 -11
  139. data/lib/generators/geoblacklight_admin/templates/devise/mailer/invitation_instructions.text.erb +0 -11
@@ -1,6 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Admin::DocumentAccessesController
4
+ #
5
+ # This controller manages the CRUD operations for DocumentAccess objects
6
+ # within the admin namespace. It provides actions to list, show, create,
7
+ # update, and destroy document access records. It also includes custom
8
+ # actions for importing and destroying all document access links.
9
+ #
10
+ # Actions:
11
+ # - index: Lists all document accesses, optionally filtered by document_id.
12
+ # - show: Displays a specific document access.
13
+ # - new: Renders a form for creating a new document access.
14
+ # - edit: Renders a form for editing an existing document access.
15
+ # - create: Creates a new document access.
16
+ # - update: Updates an existing document access.
17
+ # - destroy: Deletes a specific document access.
18
+ # - destroy_all: Deletes all document access links provided in the params.
19
+ # - import: Imports document access links from a file provided in the params.
20
+ #
21
+ # Before Actions:
22
+ # - set_document: Sets the @document instance variable if document_id is present.
23
+ # - set_document_access: Sets the @document_access instance variable for specific actions.
24
+ #
25
+ # Private Methods:
26
+ # - set_document: Finds and sets the document based on the document_id parameter.
27
+ # - set_document_access: Finds and sets the document access based on the id parameter.
28
+ # - document_access_params: Permits only trusted parameters for document access.
4
29
  module Admin
5
30
  class DocumentAccessesController < Admin::AdminController
6
31
  before_action :set_document
@@ -8,6 +33,7 @@ module Admin
8
33
 
9
34
  # GET /documents/#id/access
10
35
  # GET /documents/#id/access.json
36
+ # Lists all document accesses, optionally filtered by document_id.
11
37
  def index
12
38
  if params[:document_id]
13
39
  @document_accesses = DocumentAccess.where(friendlier_id: @document.friendlier_id).order(institution_code: :asc)
@@ -18,20 +44,24 @@ module Admin
18
44
 
19
45
  # GET /document_accesses/1
20
46
  # GET /document_accesses/1.json
47
+ # Displays a specific document access.
21
48
  def show
22
49
  end
23
50
 
24
51
  # GET /document_accesses/new
52
+ # Renders a form for creating a new document access.
25
53
  def new
26
54
  @document_access = DocumentAccess.new
27
55
  end
28
56
 
29
57
  # GET /document_accesses/1/edit
58
+ # Renders a form for editing an existing document access.
30
59
  def edit
31
60
  end
32
61
 
33
62
  # POST /document_accesses
34
63
  # POST /document_accesses.json
64
+ # Creates a new document access.
35
65
  def create
36
66
  @document_access = DocumentAccess.new(document_access_params)
37
67
  logger.debug("DA Params: #{DocumentAccess.new(document_access_params).inspect}")
@@ -52,6 +82,7 @@ module Admin
52
82
 
53
83
  # PATCH/PUT /document_accesses/1
54
84
  # PATCH/PUT /document_accesses/1.json
85
+ # Updates an existing document access.
55
86
  def update
56
87
  respond_to do |format|
57
88
  if @document_access.update(document_access_params)
@@ -68,6 +99,7 @@ module Admin
68
99
 
69
100
  # DELETE /document_accesses/1
70
101
  # DELETE /document_accesses/1.json
102
+ # Deletes a specific document access.
71
103
  def destroy
72
104
  @document_access.destroy
73
105
  respond_to do |format|
@@ -78,6 +110,8 @@ module Admin
78
110
  end
79
111
  end
80
112
 
113
+ # DELETE /document_accesses/destroy_all
114
+ # Deletes all document access links provided in the params.
81
115
  def destroy_all
82
116
  logger.debug("Destroy Access Links")
83
117
  return unless params.dig(:document_access, :assets, :file)
@@ -95,6 +129,7 @@ module Admin
95
129
 
96
130
  # GET /documents/#id/access/import
97
131
  # POST /documents/#id/access/import
132
+ # Imports document access links from a file provided in the params.
98
133
  def import
99
134
  logger.debug("Import Action")
100
135
  return unless params.dig(:document_access, :assets, :file)
@@ -113,17 +148,20 @@ module Admin
113
148
  private
114
149
 
115
150
  # Use callbacks to share common setup or constraints between actions.
151
+ # Finds and sets the document based on the document_id parameter.
116
152
  def set_document
117
153
  return unless params[:document_id] # If not nested
118
154
 
119
155
  @document = Document.includes(:leaf_representative).find_by!(friendlier_id: params[:document_id])
120
156
  end
121
157
 
158
+ # Finds and sets the document access based on the id parameter.
122
159
  def set_document_access
123
160
  @document_access = DocumentAccess.find(params[:id])
124
161
  end
125
162
 
126
163
  # Only allow a list of trusted parameters through.
164
+ # Permits only trusted parameters for document access.
127
165
  def document_access_params
128
166
  params.require(:document_access).permit(:friendlier_id, :institution_code, :access_url)
129
167
  end
@@ -1,11 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Admin::DocumentAssetsController
4
+ #
5
+ # This controller manages the document assets within the admin namespace.
6
+ # It provides actions to list, show, edit, update, destroy, and attach files
7
+ # to document assets.
8
+ #
9
+ # Before Actions:
10
+ # - set_document: Sets the document based on the document_id parameter.
11
+ # - set_document_asset: Sets the document asset based on the id parameter for specific actions.
4
12
  module Admin
5
13
  class DocumentAssetsController < Admin::AdminController
6
14
  before_action :set_document
7
15
  before_action :set_document_asset, only: %i[show edit update destroy]
8
16
 
17
+ # GET /admin/document_assets
18
+ #
19
+ # Lists all document assets. If a document_id is provided, it filters
20
+ # the assets by the specified document.
9
21
  def index
10
22
  scope = Asset
11
23
 
@@ -21,6 +33,10 @@ module Admin
21
33
  @document_assets = scope
22
34
  end
23
35
 
36
+ # GET /admin/document_assets/:id
37
+ #
38
+ # Shows a specific document asset. If the asset is stored, it also
39
+ # retrieves the fixity checks associated with the asset.
24
40
  def show
25
41
  @asset = Asset.find_by_friendlier_id!(params[:id])
26
42
 
@@ -31,17 +47,23 @@ module Admin
31
47
  @earliest_check = @checks.first
32
48
  end
33
49
 
50
+ # GET /admin/document_assets/:id/edit
51
+ #
52
+ # Renders the edit form for a specific document asset.
34
53
  def edit
35
54
  end
36
55
 
37
- # PATCH/PUT /works/1
38
- # PATCH/PUT /works/1.json
56
+ # PATCH/PUT /admin/document_assets/:id
57
+ #
58
+ # Updates a specific document asset. If successful, redirects to the
59
+ # document assets index with a success notice. Otherwise, re-renders
60
+ # the edit form with errors.
39
61
  def update
40
62
  @document_asset = Asset.find_by_friendlier_id!(params[:id])
41
63
 
42
64
  respond_to do |format|
43
65
  if @document_asset.update(document_asset_params)
44
- format.html { redirect_to admin_document_document_assets_path(@document_asset.parent), notice: "Asset was successfully updated." }
66
+ format.html { redirect_to admin_document_document_assets_path(@document), notice: "Asset was successfully updated." }
45
67
  format.json { render :show, status: :ok, location: @document_asset }
46
68
  else
47
69
  format.html { render :edit }
@@ -50,6 +72,10 @@ module Admin
50
72
  end
51
73
  end
52
74
 
75
+ # DELETE /admin/document_assets/:id
76
+ #
77
+ # Destroys a specific document asset. Redirects to the document assets
78
+ # index with a success notice.
53
79
  def destroy
54
80
  @asset = Asset.find_by_friendlier_id!(params[:id])
55
81
  @asset.destroy
@@ -63,15 +89,17 @@ module Admin
63
89
  end
64
90
  end
65
91
 
92
+ # GET /admin/document_assets/display_attach_form
93
+ #
94
+ # Displays the form to attach files to a document.
66
95
  def display_attach_form
67
96
  @document = Document.find_by_friendlier_id!(params[:document_id])
68
97
  end
69
98
 
70
- # Receives json hashes for direct uploaded files in params[:files],
71
- # and id in params[:id] (friendlier_id)
72
- # creates filesets for them and attach.
73
- #
74
99
  # POST /document/:id/ingest
100
+ #
101
+ # Attaches files to a document. Receives JSON hashes for direct uploaded
102
+ # files in params[:files] and creates filesets for them.
75
103
  def attach_files
76
104
  @parent = Document.find_by_friendlier_id!(params[:id])
77
105
 
@@ -106,6 +134,9 @@ module Admin
106
134
 
107
135
  private
108
136
 
137
+ # Strong parameters for asset.
138
+ #
139
+ # Returns a list of permitted parameters for asset creation and update.
109
140
  def asset_params
110
141
  allowed_params = [:title, :derivative_storage_type, :alt_text, :caption,
111
142
  :transcription, :english_translation,
@@ -114,19 +145,25 @@ module Admin
114
145
  params.require(:asset).permit(*allowed_params)
115
146
  end
116
147
 
148
+ # Sets the document based on the document_id parameter.
149
+ #
150
+ # If the document_id is not present, it does nothing.
117
151
  def set_document
118
152
  return unless params[:document_id] # If not nested
119
153
 
120
154
  @document = Document.includes(:leaf_representative).find_by!(friendlier_id: params[:document_id])
121
155
  end
122
156
 
157
+ # Sets the document asset based on the id parameter.
123
158
  def set_document_asset
124
159
  @document_asset = DocumentAsset.find_by_friendlier_id(params[:id])
125
160
  end
126
161
 
127
- # Only allow a list of trusted parameters through.
162
+ # Strong parameters for document asset.
163
+ #
164
+ # Returns a list of permitted parameters for document asset update.
128
165
  def document_asset_params
129
- params.require(:asset).permit(:title, :label, :dct_references_uri_key)
166
+ params.require(:asset).permit(:parent_id, :title, :label, :dct_references_uri_key, :thumbnail)
130
167
  end
131
168
  end
132
169
  end
@@ -0,0 +1,172 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Admin::DocumentDistributionsController
4
+ #
5
+ # This controller manages the CRUD operations for Document Distributions within the Admin namespace.
6
+ # It includes actions for listing, showing, creating, updating, and deleting document distributions.
7
+ # Additionally, it provides functionality for importing and destroying all distributions.
8
+ module Admin
9
+ class DocumentDistributionsController < Admin::AdminController
10
+ before_action :set_document
11
+ before_action :set_document_distribution, only: %i[show edit update destroy]
12
+
13
+ # GET /admin/document_distributions or /admin/document_distributions.json
14
+ #
15
+ # Lists all document distributions. If a document_id is provided, it lists distributions
16
+ # associated with that document, ordered by position. Otherwise, it paginates all
17
+ # document distributions.
18
+ def index
19
+ @document_distributions = DocumentDistribution.all
20
+ if params[:document_id]
21
+ @document_distributions = DocumentDistribution.where(friendlier_id: @document.friendlier_id).order(position: :asc)
22
+ else
23
+ @pagy, @document_distributions = pagy(DocumentDistribution.all.order(friendlier_id: :asc, updated_at: :desc), items: 20)
24
+ end
25
+ end
26
+
27
+ # GET /admin/document_distributions/1 or /admin/document_distributions/1.json
28
+ #
29
+ # Shows a specific document distribution.
30
+ def show
31
+ end
32
+
33
+ # GET /admin/document_references/new
34
+ #
35
+ # Initializes a new document distribution.
36
+ def new
37
+ @document_distribution = DocumentDistribution.new
38
+ end
39
+
40
+ # GET /admin/document_distributions/1/edit
41
+ #
42
+ # Edits an existing document distribution.
43
+ def edit
44
+ end
45
+
46
+ # POST /admin/document_distributions or /admin/document_distributions.json
47
+ #
48
+ # Creates a new document distribution. If successful, redirects to the document distributions
49
+ # list with a success notice. Otherwise, renders the new form with errors.
50
+ def create
51
+ @document_distribution = DocumentDistribution.new(document_distribution_params)
52
+
53
+ respond_to do |format|
54
+ if @document_distribution.save
55
+ format.html { redirect_to admin_document_document_distributions_path(@document), notice: "Document distribution was successfully created." }
56
+ format.json { render :show, status: :created, location: @document_distribution }
57
+ else
58
+ format.html { render :new, status: :unprocessable_entity }
59
+ format.json { render json: @document_distribution.errors, status: :unprocessable_entity }
60
+ end
61
+ end
62
+ end
63
+
64
+ # PATCH/PUT /admin/document_distributions/1 or /admin/document_distributions/1.json
65
+ #
66
+ # Updates an existing document distribution. If successful, redirects to the document distribution
67
+ # with a success notice. Otherwise, renders the edit form with errors.
68
+ def update
69
+ respond_to do |format|
70
+ if @document_distribution.update(document_distribution_params)
71
+ format.html { redirect_to admin_document_document_distributions_path(@document), notice: "Document distribution was successfully updated." }
72
+ format.json { render :show, status: :ok, location: @document_distribution }
73
+ else
74
+ format.html { render :edit, status: :unprocessable_entity }
75
+ format.json { render json: @document_distribution.errors, status: :unprocessable_entity }
76
+ end
77
+ end
78
+ end
79
+
80
+ # DELETE /admin/document_distributions/1 or /admin/document_distributions/1.json
81
+ #
82
+ # Deletes a document distribution. Redirects to the document distributions list with a success notice.
83
+ def destroy
84
+ @document_distribution.destroy!
85
+
86
+ respond_to do |format|
87
+ format.html { redirect_to admin_document_document_distributions_path(@document), status: :see_other, notice: "Document distribution was successfully destroyed." }
88
+ format.json { head :no_content }
89
+ end
90
+ end
91
+
92
+ # DELETE /admin/document_distributions/destroy_all
93
+ #
94
+ # Destroys all document distributions provided in the file parameter. If successful, redirects
95
+ # with a success notice. Otherwise, redirects with an error notice.
96
+ def destroy_all
97
+ return if request.get?
98
+
99
+ logger.debug("Destroy Distributions")
100
+ unless params.dig(:document_distribution, :distributions, :file)
101
+ raise ArgumentError, "File does not exist or is invalid."
102
+ end
103
+
104
+ respond_to do |format|
105
+ if DocumentDistribution.destroy_all(params.dig(:document_distribution, :distributions, :file))
106
+ format.html { redirect_to admin_document_distributions_path, notice: "Distributions were destroyed." }
107
+ else
108
+ format.html { redirect_to admin_document_distributions_path, notice: "Distributions could not be destroyed." }
109
+ end
110
+ rescue => e
111
+ format.html { redirect_to admin_document_distributions_path, notice: "Distributions could not be destroyed. #{e}" }
112
+ end
113
+ end
114
+
115
+ # GET/POST /documents/1/distributions/import
116
+ #
117
+ # Imports document distributions from a file. If successful, redirects with a success notice.
118
+ # Otherwise, redirects with an error notice.
119
+ def import
120
+ return if request.get?
121
+
122
+ logger.debug("Import Distributions")
123
+
124
+ unless params.dig(:document_distribution, :distributions, :file)
125
+ raise ArgumentError, "File does not exist or is invalid."
126
+ end
127
+
128
+ if DocumentDistribution.import(params.dig(:document_distribution, :distributions, :file))
129
+ logger.debug("Distributions were created successfully.")
130
+ if params[:document_id]
131
+ redirect_to admin_document_document_distributions_path(@document), notice: "Distributions were created successfully."
132
+ else
133
+ redirect_to admin_document_document_distributions_path, notice: "Distributions were created successfully."
134
+ end
135
+ else
136
+ logger.debug("Distributions could not be created.")
137
+ if params[:document_id]
138
+ redirect_to admin_document_document_distributions_path(@document), warning: "Distributions could not be created."
139
+ else
140
+ redirect_to admin_document_document_distributions_path, warning: "Distributions could not be created."
141
+ end
142
+ end
143
+ rescue => e
144
+ logger.debug("Distributions could not be created. #{e}")
145
+ if params[:document_id]
146
+ redirect_to admin_document_document_distributions_path(@document), notice: "Distributions could not be created. #{e}"
147
+ else
148
+ redirect_to admin_document_document_distributions_path, notice: "Distributions could not be created. #{e}"
149
+ end
150
+ end
151
+
152
+ private
153
+
154
+ # Sets the document based on the document_id parameter.
155
+ # If not nested, it does nothing.
156
+ def set_document
157
+ return unless params[:document_id] # If not nested
158
+
159
+ @document = Document.includes(:leaf_representative).find_by!(friendlier_id: params[:document_id])
160
+ end
161
+
162
+ # Sets the document distribution based on the id parameter.
163
+ def set_document_distribution
164
+ @document_distribution = DocumentDistribution.find(params[:id])
165
+ end
166
+
167
+ # Permits only the trusted parameters for document distributions.
168
+ def document_distribution_params
169
+ params.require(:document_distribution).permit(:friendlier_id, :reference_type_id, :url, :label, :position)
170
+ end
171
+ end
172
+ end
@@ -1,17 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Admin::DocumentsController
4
+ # This controller handles the management of documents within the admin interface.
5
+ # It provides actions to list, create, update, and delete documents, as well as
6
+ # export them in various formats.
4
7
  module Admin
5
8
  class DocumentsController < Admin::AdminController
9
+ # Allow all parameters (not recommended for production use)
6
10
  ActionController::Parameters.permit_all_parameters = true
7
- before_action :set_document,
8
- only: %i[show edit update destroy admin versions]
11
+
12
+ # Set the document before certain actions
13
+ before_action :set_document, only: %i[show edit update destroy admin versions]
9
14
 
10
15
  # GET /documents
11
16
  # GET /documents.json
17
+ # Lists all documents with support for various export formats.
12
18
  def index
19
+ # Construct the request URL
13
20
  @request = "#{request.protocol}#{request.host}:#{request.port}"
14
21
 
22
+ # Define query parameters for the document search
15
23
  query_params = {
16
24
  q: params["q"],
17
25
  f: params["f"],
@@ -22,56 +30,47 @@ module Admin
22
30
  }
23
31
  @documents = BlacklightApi.new(@request, **query_params)
24
32
 
33
+ # Respond to different formats
25
34
  respond_to do |format|
26
35
  format.html { render :index }
27
36
  format.json { render json: @documents.results.to_json }
28
-
29
- # JSON - BTAA Aardvark
30
37
  format.json_btaa_aardvark do
31
- ExportJsonJob.perform_later(@request, current_user, query_params.merge!({format: "json_btaa_aardvark"}),
32
- ExportJsonService)
38
+ ExportJsonJob.perform_later(@request, current_user, query_params.merge!({format: "json_btaa_aardvark"}), ExportJsonService)
33
39
  head :no_content
34
40
  end
35
-
36
- # JSON - GBL Aardvark
37
41
  format.json_aardvark do
38
42
  ExportJsonJob.perform_later(@request, current_user, query_params.merge!({format: "json_aardvark"}), ExportJsonService)
39
43
  head :no_content
40
44
  end
41
-
42
- # JSON - GBL v1
43
45
  format.json_gbl_v1 do
44
46
  ExportJsonJob.perform_later(@request, current_user, query_params.merge!({format: "json_gbl_v1"}), ExportJsonService)
45
47
  head :no_content
46
48
  end
47
-
48
- # JSON - FILE
49
49
  format.json_file do
50
50
  ExportJsonBulkJob.perform_later(@request, current_user, query_params.merge!({format: "json_file"}), ExportJsonService)
51
51
  head :no_content
52
52
  end
53
-
54
- # CSV - B1G
55
53
  format.csv do
56
54
  ExportJob.perform_later(@request, current_user, query_params, ExportCsvService)
57
55
  head :no_content
58
56
  end
59
-
60
- # CSV Document Downloads - B1G
61
57
  format.csv_document_downloads do
62
58
  ExportJob.perform_later(@request, current_user, query_params, ExportCsvDocumentDownloadsService)
63
59
  head :no_content
64
60
  end
65
-
66
- # CSV Document Access Links - B1G
67
61
  format.csv_document_access_links do
68
62
  ExportJob.perform_later(@request, current_user, query_params, ExportCsvDocumentAccessLinksService)
69
63
  head :no_content
70
64
  end
65
+ format.csv_document_distributions do
66
+ ExportJob.perform_later(@request, current_user, query_params, ExportCsvDocumentDistributionsService)
67
+ head :no_content
68
+ end
71
69
  end
72
70
  end
73
71
 
74
- # Fetch documents from array of friendlier_ids
72
+ # Fetch documents from an array of friendlier_ids
73
+ # This action retrieves documents based on their friendlier IDs.
75
74
  def fetch
76
75
  @request = "#{request.protocol}#{request.host}:#{request.port}"
77
76
  @documents = Document.where(friendlier_id: params["ids"])
@@ -79,71 +78,62 @@ module Admin
79
78
  respond_to do |format|
80
79
  format.html { render :index }
81
80
  format.json { render json: @documents.to_json }
82
-
83
- # JSON - BTAA Aardvark
84
81
  format.json_btaa_aardvark do
85
- ExportJsonJob.perform_later(@request, current_user, {ids: @documents.pluck(:friendlier_id), format: "json_btaa_aardvark"},
86
- ExportJsonService)
82
+ ExportJsonJob.perform_later(@request, current_user, {ids: @documents.pluck(:friendlier_id), format: "json_btaa_aardvark"}, ExportJsonService)
87
83
  head :no_content
88
84
  end
89
-
90
- # JSON - GBL Aardvark
91
85
  format.json_aardvark do
92
- ExportJsonJob.perform_later(@request, current_user, {ids: @documents.pluck(:friendlier_id), format: "json_aardvark"},
93
- ExportJsonService)
86
+ ExportJsonJob.perform_later(@request, current_user, {ids: @documents.pluck(:friendlier_id), format: "json_aardvark"}, ExportJsonService)
94
87
  head :no_content
95
88
  end
96
-
97
- # JSON - GBL v1
98
89
  format.json_gbl_v1 do
99
- ExportJsonJob.perform_later(@request, current_user, {ids: @documents.pluck(:friendlier_id), format: "json_gbl_v1"},
100
- ExportJsonService)
90
+ ExportJsonJob.perform_later(@request, current_user, {ids: @documents.pluck(:friendlier_id), format: "json_gbl_v1"}, ExportJsonService)
101
91
  head :no_content
102
92
  end
103
-
104
- # CSV - B1G
105
93
  format.csv do
106
- ExportJob.perform_later(@request, current_user, {ids: @documents.pluck(:friendlier_id), format: "csv"},
107
- ExportCsvService)
94
+ ExportJob.perform_later(@request, current_user, {ids: @documents.pluck(:friendlier_id), format: "csv"}, ExportCsvService)
108
95
  head :no_content
109
96
  end
110
-
111
- # CSV Document Downloads - B1G
112
97
  format.csv_document_downloads do
113
- ExportJob.perform_later(@request, current_user,
114
- {ids: @documents.pluck(:friendlier_id), format: "csv_document_downloads"}, ExportCsvDocumentDownloadsService)
98
+ ExportJob.perform_later(@request, current_user, {ids: @documents.pluck(:friendlier_id), format: "csv_document_downloads"}, ExportCsvDocumentDownloadsService)
115
99
  head :no_content
116
100
  end
117
-
118
- # CSV Document Downloads - B1G
119
101
  format.csv_document_access_links do
120
- ExportJob.perform_later(@request, current_user,
121
- {ids: @documents.pluck(:friendlier_id), format: "csv_document_access_links"}, ExportCsvDocumentAccessLinksService)
102
+ ExportJob.perform_later(@request, current_user, {ids: @documents.pluck(:friendlier_id), format: "csv_document_access_links"}, ExportCsvDocumentAccessLinksService)
103
+ head :no_content
104
+ end
105
+ format.csv_document_distributions do
106
+ ExportJob.perform_later(@request, current_user, {ids: @documents.pluck(:friendlier_id), format: "csv_document_distributions"}, ExportCsvDocumentDistributionsService)
122
107
  head :no_content
123
108
  end
124
109
  end
125
110
  end
126
111
 
127
112
  # GET /documents/new
113
+ # Renders a form for creating a new document.
128
114
  def new
129
115
  @document = Document.new
130
116
  render :edit
131
117
  end
132
118
 
133
119
  # GET /documents/1/edit
120
+ # Renders a form for editing an existing document.
134
121
  def edit
135
122
  end
136
123
 
137
124
  # GET /documents/1/admin
125
+ # Admin view for a specific document.
138
126
  def admin
139
127
  end
140
128
 
141
129
  # GET /documents/1/versions
130
+ # Displays the version history of a document.
142
131
  def versions
143
132
  end
144
133
 
145
134
  # POST /documents
146
135
  # POST /documents.json
136
+ # Creates a new document with the provided parameters.
147
137
  def create
148
138
  @document = Document.new(document_params)
149
139
  @document.friendlier_id = @document.send(GeoblacklightAdmin::Schema.instance.solr_fields[:id])
@@ -160,6 +150,7 @@ module Admin
160
150
 
161
151
  # PATCH/PUT /documents/1
162
152
  # PATCH/PUT /documents/1.json
153
+ # Updates an existing document with the provided parameters.
163
154
  def update
164
155
  respond_to do |format|
165
156
  if @document.update(document_params)
@@ -174,6 +165,7 @@ module Admin
174
165
 
175
166
  # DELETE /documents/1
176
167
  # DELETE /documents/1.json
168
+ # Deletes a document.
177
169
  def destroy
178
170
  @document.destroy
179
171
  respond_to do |format|
@@ -184,6 +176,8 @@ module Admin
184
176
  end
185
177
  end
186
178
 
179
+ # GET /documents/1
180
+ # Shows a document in various formats.
187
181
  def show
188
182
  respond_to do |format|
189
183
  format.html { redirect_to edit_admin_document_url(@document) }
@@ -191,37 +185,29 @@ module Admin
191
185
  format.json_aardvark
192
186
  format.json_btaa_aardvark
193
187
  format.json_gbl_v1
194
- # B1G CSV
195
188
  format.csv { send_data collect_csv([@document]), filename: "documents-#{Time.zone.today}.csv" }
196
-
197
- # @TODO:
198
- # geoblacklight_version: 1.0 (strict)
199
- # geoblacklight_version: 1.0 + B1G customizations
200
- # geoblacklight_version: 2.0 (strict)
201
- # geoblacklight_version: 2.0 + B1G customizations
202
189
  end
203
190
  end
204
191
 
205
192
  private
206
193
 
207
194
  # Use callbacks to share common setup or constraints between actions.
195
+ # Finds and sets the document based on the friendlier_id.
208
196
  def set_document
209
197
  @document = Document.includes(:leaf_representative).find_by!(friendlier_id: params[:id] || params[:document_id])
210
198
  end
211
199
 
212
- # only allow whitelisted params through (TODO, we're allowing all document params!)
213
- # Plus sanitization or any other mutation.
214
- #
215
- # This could be done in a form object or otherwise abstracted, but this is good
216
- # enough for now.
200
+ # Defines the list of permitted parameters for document creation and updates.
217
201
  def permittable_params
218
202
  %i[title publication_state layer_geom_type_s dct_references_s q f page sort rows daterange]
219
203
  end
220
204
 
205
+ # Strong parameters for document creation and updates.
221
206
  def document_params
222
207
  Kithe::Parameters.new(params).require(:document).permit_attr_json(Document).permit(permittable_params)
223
208
  end
224
209
 
210
+ # Collects documents into a CSV format.
225
211
  def collect_csv(documents)
226
212
  CSV.generate(headers: true) do |csv|
227
213
  csv << GeoblacklightAdmin::Schema.instance.exportable_fields.map { |k, _v| k.to_s }