geoblacklight_admin 0.6.3 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -1
  3. data/app/assets/stylesheets/geoblacklight_admin/_core.scss +2 -1
  4. data/app/assets/stylesheets/geoblacklight_admin/modules/_icons.scss +9 -0
  5. data/app/assets/stylesheets/geoblacklight_admin/modules/_pagy.scss +7 -0
  6. data/app/controllers/admin/document_data_dictionaries_controller.rb +126 -0
  7. data/app/controllers/admin/document_data_dictionary_entries_controller.rb +124 -0
  8. data/app/controllers/admin/document_distributions_controller.rb +0 -38
  9. data/app/controllers/admin/import_distributions_controller.rb +126 -0
  10. data/app/controllers/concerns/blacklight/catalog.rb +373 -0
  11. data/app/helpers/facets_helper.rb +19 -0
  12. data/app/javascript/index.js +1 -1
  13. data/app/jobs/import_distributions_run_job.rb +32 -0
  14. data/app/jobs/import_document_distribution_job.rb +23 -0
  15. data/app/models/document.rb +5 -0
  16. data/app/models/document_data_dictionary/csv_header_validator.rb +30 -0
  17. data/app/models/document_data_dictionary.rb +39 -0
  18. data/app/models/document_data_dictionary_entry.rb +9 -0
  19. data/app/models/import_distribution/csv_header_validator.rb +32 -0
  20. data/app/models/import_distribution.rb +55 -0
  21. data/app/models/import_distribution_state_machine.rb +14 -0
  22. data/app/models/import_distribution_transition.rb +26 -0
  23. data/app/models/import_document_distribution.rb +25 -0
  24. data/app/models/import_document_distribution_state_machine.rb +13 -0
  25. data/app/models/import_document_distribution_transition.rb +19 -0
  26. data/app/views/admin/document_data_dictionaries/_data_dictionaries_table.html.erb +40 -0
  27. data/app/views/admin/document_data_dictionaries/_document_data_dictionary.html.erb +37 -0
  28. data/app/views/admin/document_data_dictionaries/_document_data_dictionary.json.jbuilder +2 -0
  29. data/app/views/admin/document_data_dictionaries/_form.html.erb +17 -0
  30. data/app/views/admin/document_data_dictionaries/edit.html.erb +12 -0
  31. data/app/views/admin/document_data_dictionaries/index.html.erb +45 -0
  32. data/app/views/admin/document_data_dictionaries/index.json.jbuilder +1 -0
  33. data/app/views/admin/document_data_dictionaries/new.html.erb +78 -0
  34. data/app/views/admin/document_data_dictionaries/show.html.erb +78 -0
  35. data/app/views/admin/document_data_dictionaries/show.json.jbuilder +1 -0
  36. data/app/views/admin/document_data_dictionary_entries/_form.html.erb +19 -0
  37. data/app/views/admin/document_data_dictionary_entries/edit.html.erb +12 -0
  38. data/app/views/admin/document_data_dictionary_entries/new.html.erb +16 -0
  39. data/app/views/admin/document_distributions/index.html.erb +2 -2
  40. data/app/views/admin/documents/_form_nav.html.erb +4 -0
  41. data/app/views/admin/import_distributions/_form.html.erb +21 -0
  42. data/app/views/admin/import_distributions/_import_distribution.json.jbuilder +5 -0
  43. data/app/views/admin/import_distributions/_show_failed_tab.html.erb +36 -0
  44. data/app/views/admin/import_distributions/_show_success_tab.html.erb +35 -0
  45. data/app/views/admin/import_distributions/edit.html.erb +8 -0
  46. data/app/views/admin/import_distributions/index.html.erb +58 -0
  47. data/app/views/admin/import_distributions/index.json.jbuilder +3 -0
  48. data/app/views/admin/import_distributions/new.html.erb +7 -0
  49. data/app/views/admin/import_distributions/show.html.erb +121 -0
  50. data/app/views/admin/import_distributions/show.json.jbuilder +3 -0
  51. data/app/views/admin/imports/index.html.erb +2 -2
  52. data/app/views/admin/shared/_navbar.html.erb +2 -2
  53. data/app/views/catalog/_facet_pagination.html.erb +6 -0
  54. data/app/views/catalog/_gbl_admin_data_dictionaries.html.erb +3 -0
  55. data/app/views/catalog/_paginate_compact.html.erb +9 -0
  56. data/app/views/catalog/_results_pagination.html.erb +9 -0
  57. data/app/views/catalog/_show_gbl_admin_data_dictionaries.html.erb +44 -0
  58. data/app/views/catalog/data_dictionaries.html.erb +12 -0
  59. data/db/migrate/20241204163117_create_document_data_dictionaries.rb +14 -0
  60. data/db/migrate/20241218174455_create_document_data_dictionary_entries.rb +17 -0
  61. data/db/migrate/20250113213655_import_distributions.rb +56 -0
  62. data/lib/generators/geoblacklight_admin/config_generator.rb +61 -4
  63. data/lib/generators/geoblacklight_admin/templates/btaa_sample_document_data_dictionary_entries.csv +9 -0
  64. data/lib/generators/geoblacklight_admin/templates/btaa_sample_document_distributions.csv +17 -0
  65. data/lib/generators/geoblacklight_admin/templates/config/initializers/pagy.rb +53 -83
  66. data/lib/geoblacklight_admin/engine.rb +1 -0
  67. data/lib/geoblacklight_admin/routes/data_dictionariesable.rb +17 -0
  68. data/lib/geoblacklight_admin/version.rb +1 -1
  69. metadata +61 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: faa51021e7c742dbc13abb29e2114de5f917716955034cff20b433d6a3c275de
4
- data.tar.gz: 71050ece81fb99a0377793467e09e4bb0d67fc892b6f49296a1c278ab4a00460
3
+ metadata.gz: 3206d757d63794d306ce29d80d7bcf7ea9e2afe7f94f21792885a71e3edc9ac6
4
+ data.tar.gz: 1916a1e90a1826bb509a497b6bab3c4f3253e44cac7f44f73e6f676638c78f91
5
5
  SHA512:
6
- metadata.gz: 7fef4d2444d40f92f7731471f3647959b440e0a1ff9d74f5fb4973bff02701b626a6b0d83c7175e8bc0a0bb9bc7519edb3ef3f660d1584b0e4bbc22cb9f4df30
7
- data.tar.gz: 3cc6ed9f3b4f25c67b30ba05a601a05022baab8ace7081d609db514f175746d43a5e91225c2889d8963eb74fbf96cca96f4cd112fae5066d65b455eb6cf3d72e
6
+ metadata.gz: '09f174737d687d2a9d60a9a5a6fb73d11eefaf160ec2862a2ff0d12e4b926ab8b0b91d534ae4b20d781319b1b50107dd05cb214c54ffdc6c531bb600ca139c5b'
7
+ data.tar.gz: af6d3f3e20943a2a8de0a1020d0a568e2870738c5c74d21ef9aad575fd9364360c620e78c2d16cead8261f77501c8a05c095ea94747801be4a63b81e3421af0e
data/README.md CHANGED
@@ -69,7 +69,8 @@ The gem is available as open source under the terms of the [Apache 2.0 License](
69
69
  * ~~Debug Rails 7.2 support (remove devise_invitable, see [#915](https://github.com/scambra/devise_invitable/issues/915))~~
70
70
  * ~~Separate dct_references_s support into a separate model~~
71
71
  * ~~Import/Export dct_references_s outside of the main document model~~
72
- * Data Dictionary: Add support for `document_data_dictionary`
72
+ * ~~Distributions: Move import to background queue~~
73
+ * ~~Data Dictionary: Add support for `document_data_dictionary`~~
73
74
  * Gazetteer: Add GeoNames support
74
75
  * Gazetteer: Add Who's On First support
75
76
  * Gazetteer: Add Ollama support
@@ -14,7 +14,7 @@
14
14
  @import "settings/variables";
15
15
 
16
16
  // Vendors
17
- @import 'bootstrap';
17
+ @import "bootstrap";
18
18
 
19
19
  // Modules
20
20
  @import "modules/autocomplete";
@@ -27,6 +27,7 @@
27
27
  @import "modules/icons";
28
28
  @import "modules/images";
29
29
  @import "modules/nav";
30
+ @import "modules/pagy";
30
31
  @import "modules/results";
31
32
  @import "modules/tables";
32
33
  @import "modules/toasts";
@@ -13,3 +13,12 @@ svg.icon.baseline {
13
13
  top: -0.125em;
14
14
  position: relative;
15
15
  }
16
+
17
+ // Sidebar Action Icons
18
+ #dataDictionariesLink {
19
+ margin-left:0rem;
20
+ padding-left: 1.5rem;
21
+ background-position: left center;
22
+ background-repeat:no-repeat;
23
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1' width='14' height='14' viewBox='0 0 512 512' aria-label='Table' role='img'%3E%3Ctitle%3ETable%3C/title%3E%3Cpath fill='%236c757d' d='M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM48 80h416v64H48V80zm0 128h128v64H48v-64zm0 128h128v64H48v-64zm192 64v-64h128v64H240zm128-128H240v-64h128v64zm64 128v-64h128v64H432zm0-128h128v64H432v-64z'%3E%3C/path%3E%3C/svg%3E");
24
+ }
@@ -0,0 +1,7 @@
1
+ .pagy {
2
+ a:not(.gap) {
3
+ &:not([href]) { /* disabled links */
4
+ margin-top: 0.4rem;
5
+ }
6
+ }
7
+ }
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Admin::DocumentDataDictionariesController
4
+ #
5
+ # This controller manages the document data dictionaries within the admin namespace.
6
+ # It provides actions to list, show, edit, update, and destroy data dictionaries.
7
+ module Admin
8
+ class DocumentDataDictionariesController < Admin::AdminController
9
+ before_action :set_document
10
+ before_action :set_document_data_dictionary, only: %i[show edit update destroy]
11
+
12
+ # GET /document_data_dictionaries or /document_data_dictionaries.json
13
+ def index
14
+ @document_data_dictionaries = DocumentDataDictionary.all
15
+ if params[:document_id]
16
+ @document_data_dictionaries = DocumentDataDictionary.where(friendlier_id: @document.friendlier_id).order(position: :asc)
17
+ else
18
+ @pagy, @document_data_dictionaries = pagy(DocumentDataDictionary.all.order(friendlier_id: :asc, updated_at: :desc), items: 20)
19
+ end
20
+ end
21
+
22
+ # GET /document_data_dictionaries/1 or /document_data_dictionaries/1.json
23
+ def show
24
+ @pagy, @document_data_dictionary_entries = pagy(@document_data_dictionary.document_data_dictionary_entries.order(position: :asc), items: 100)
25
+ end
26
+
27
+ # GET /document_data_dictionaries/new
28
+ def new
29
+ @document_data_dictionary = DocumentDataDictionary.new
30
+ end
31
+
32
+ # GET /document_data_dictionaries/1/edit
33
+ def edit
34
+ end
35
+
36
+ # POST /document_data_dictionaries or /document_data_dictionaries.json
37
+ def create
38
+ @document_data_dictionary = DocumentDataDictionary.new(document_data_dictionary_params)
39
+
40
+ respond_to do |format|
41
+ if @document_data_dictionary.save
42
+ format.html { redirect_to admin_document_document_data_dictionaries_path(@document), notice: "Document data dictionary was successfully created." }
43
+ format.json { render :show, status: :created, location: @document_data_dictionary }
44
+ else
45
+ logger.debug("Document data dictionary could not be created. #{@document_data_dictionary.errors.full_messages}")
46
+ format.html { render :new, status: :unprocessable_entity }
47
+ format.json { render json: @document_data_dictionary.errors, status: :unprocessable_entity }
48
+ end
49
+ end
50
+ end
51
+
52
+ # PATCH/PUT /document_data_dictionaries/1 or /document_data_dictionaries/1.json
53
+ def update
54
+ respond_to do |format|
55
+ if @document_data_dictionary.update(document_data_dictionary_params)
56
+ format.html { redirect_to admin_document_document_data_dictionaries_path(@document), notice: "Document data dictionary was successfully updated." }
57
+ format.json { render :show, status: :ok, location: @document_data_dictionary }
58
+ else
59
+ format.html { render :edit, status: :unprocessable_entity }
60
+ format.json { render json: @document_data_dictionary.errors, status: :unprocessable_entity }
61
+ end
62
+ end
63
+ end
64
+
65
+ # DELETE /document_data_dictionaries/1 or /document_data_dictionaries/1.json
66
+ def destroy
67
+ @document_data_dictionary.destroy!
68
+
69
+ respond_to do |format|
70
+ format.html { redirect_to admin_document_document_data_dictionaries_path(@document), status: :see_other, notice: "Document data dictionary was successfully destroyed." }
71
+ format.json { head :no_content }
72
+ end
73
+ end
74
+
75
+ # DELETE /admin/document_data_dictionaries/destroy_all
76
+ #
77
+ # Destroys all document data dictionaries provided in the file parameter. If successful, redirects
78
+ # with a success notice. Otherwise, redirects with an error notice.
79
+ def destroy_all
80
+ return if request.get?
81
+
82
+ logger.debug("Destroy Data Dictionaries")
83
+ unless params.dig(:document_data_dictionary, :data_dictionaries, :file)
84
+ raise ArgumentError, "File does not exist or is invalid."
85
+ end
86
+
87
+ respond_to do |format|
88
+ if DocumentDataDictionary.destroy_all(params.dig(:document_data_dictionary, :data_dictionaries, :file))
89
+ format.html { redirect_to admin_document_document_data_dictionaries_path, notice: "Data dictionaries were destroyed." }
90
+ else
91
+ format.html { redirect_to admin_document_document_data_dictionaries_path, notice: "Data dictionaries could not be destroyed." }
92
+ end
93
+ rescue => e
94
+ format.html { redirect_to admin_document_document_data_dictionaries_path, notice: "Data dictionaries could not be destroyed. #{e}" }
95
+ end
96
+ end
97
+
98
+ private
99
+
100
+ # Sets the document based on the document_id parameter.
101
+ # If not nested, it does nothing.
102
+ def set_document
103
+ return unless params[:document_id] # If not nested
104
+
105
+ @document = Document.includes(:leaf_representative).find_by!(friendlier_id: params[:document_id])
106
+ end
107
+
108
+ # Sets the document data dictionary based on the id parameter.
109
+ def set_document_data_dictionary
110
+ @document_data_dictionary = DocumentDataDictionary.find(params[:id])
111
+ end
112
+
113
+ # Only allow a list of trusted parameters through.
114
+ def document_data_dictionary_params
115
+ params.require(:document_data_dictionary).permit(
116
+ :friendlier_id,
117
+ :name,
118
+ :description,
119
+ :staff_notes,
120
+ :tags,
121
+ :csv_file,
122
+ :position
123
+ )
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Admin::DocumentDataDictionaryEntriesController
4
+ #
5
+ # This controller manages the document data dictionary entries within the admin namespace.
6
+ # It provides actions to list, show, edit, update, destroy, and import data dictionaries.
7
+ module Admin
8
+ class DocumentDataDictionaryEntriesController < Admin::AdminController
9
+ before_action :set_document
10
+ before_action :set_document_data_dictionary
11
+ before_action :set_document_data_dictionary_entry, only: %i[edit update destroy]
12
+
13
+ # GET /document_data_dictionaries/1/entries/new
14
+ def new
15
+ @document_data_dictionary_entry = DocumentDataDictionaryEntry.new
16
+ end
17
+
18
+ # GET /document_data_dictionaries/1/entries/1/edit
19
+ def edit
20
+ end
21
+
22
+ # POST /document_data_dictionaries/1/entries or /document_data_dictionaries/1/entries.json
23
+ def create
24
+ @document_data_dictionary_entry = DocumentDataDictionaryEntry.new(document_data_dictionary_entry_params)
25
+
26
+ respond_to do |format|
27
+ if @document_data_dictionary_entry.save
28
+ format.html { redirect_to admin_document_document_data_dictionary_path(@document, @document_data_dictionary), notice: "Document data dictionary entry was successfully created." }
29
+ format.json { render :show, status: :created, location: @document_data_dictionary_entry }
30
+ else
31
+ logger.debug("Document data dictionary entry could not be created. #{@document_data_dictionary_entry.errors.full_messages}")
32
+ format.html { render :new, status: :unprocessable_entity }
33
+ format.json { render json: @document_data_dictionary_entry.errors, status: :unprocessable_entity }
34
+ end
35
+ end
36
+ end
37
+
38
+ # PATCH/PUT /document_data_dictionaries/1/entries/1 or /document_data_dictionaries/1/entries/1.json
39
+ def update
40
+ respond_to do |format|
41
+ if @document_data_dictionary_entry.update(document_data_dictionary_entry_params)
42
+ format.html { redirect_to admin_document_document_data_dictionary_path(@document, @document_data_dictionary), notice: "Document data dictionary entry was successfully updated." }
43
+ format.json { render :show, status: :ok, location: @document_data_dictionary_entry }
44
+ else
45
+ logger.debug("Document data dictionary entry could not be updated. #{@document_data_dictionary_entry.errors.full_messages}")
46
+ format.html { render :edit, status: :unprocessable_entity }
47
+ format.json { render json: @document_data_dictionary_entry.errors, status: :unprocessable_entity }
48
+ end
49
+ end
50
+ end
51
+
52
+ # DELETE /document_data_dictionaries/1/entries/1 or /document_data_dictionaries/1/entries/1.json
53
+ def destroy
54
+ @document_data_dictionary_entry.destroy!
55
+
56
+ respond_to do |format|
57
+ format.html { redirect_to admin_document_document_data_dictionary_path(@document, @document_data_dictionary), status: :see_other, notice: "Document data dictionary entry was successfully destroyed." }
58
+ format.json { head :no_content }
59
+ end
60
+ end
61
+
62
+ # DELETE /admin/document_data_dictionaries/1/entries/destroy_all
63
+ #
64
+ # Destroys all document data dictionaries provided in the file parameter. If successful, redirects
65
+ # with a success notice. Otherwise, redirects with an error notice.
66
+ def destroy_all
67
+ return if request.get?
68
+
69
+ logger.debug("Destroy Data Dictionary Entries")
70
+
71
+ respond_to do |format|
72
+ if @document_data_dictionary.document_data_dictionary_entries.destroy_all
73
+ format.html { redirect_to admin_document_document_data_dictionary_document_data_dictionary_entries_path(@document_data_dictionary.friendlier_id, @document_data_dictionary), notice: "Data dictionary entries were destroyed." }
74
+ else
75
+ format.html { redirect_to admin_document_document_data_dictionary_document_data_dictionary_entries_path(@document_data_dictionary.friendlier_id, @document_data_dictionary), notice: "Data dictionary entries could not be destroyed." }
76
+ end
77
+ rescue => e
78
+ format.html { redirect_to admin_document_document_data_dictionary_document_data_dictionary_entries_path(@document_data_dictionary.friendlier_id, @document_data_dictionary), notice: "Data dictionary entries could not be destroyed. #{e}" }
79
+ end
80
+ end
81
+
82
+ # POST /document_data_dictionaries/1/entries/sort
83
+ # Sorts document data dictionary entries based on the provided list of IDs.
84
+ # Renders an empty response body.
85
+ def sort
86
+ DocumentDataDictionary.sort_entries(params[:id_list])
87
+ render body: nil
88
+ end
89
+
90
+ private
91
+
92
+ # Sets the document based on the document_id parameter.
93
+ # If not nested, it does nothing.
94
+ def set_document
95
+ return unless params[:document_id] # If not nested
96
+ @document = Document.includes(:leaf_representative).find_by!(friendlier_id: params[:document_id])
97
+ end
98
+
99
+ # Sets the document data dictionary based on the id parameter.
100
+ def set_document_data_dictionary
101
+ @document_data_dictionary = DocumentDataDictionary.find(params[:document_data_dictionary_id])
102
+ end
103
+
104
+ # Sets the document data dictionary entry based on the id parameter.
105
+ def set_document_data_dictionary_entry
106
+ @document_data_dictionary_entry = DocumentDataDictionaryEntry.find(params[:id])
107
+ end
108
+
109
+ # Only allow a list of trusted parameters through.
110
+ def document_data_dictionary_entry_params
111
+ params.require(:document_data_dictionary_entry).permit(
112
+ :friendlier_id,
113
+ :document_data_dictionary_id,
114
+ :field_name,
115
+ :field_type,
116
+ :values,
117
+ :definition,
118
+ :definition_source,
119
+ :parent_field_name,
120
+ :position
121
+ )
122
+ end
123
+ end
124
+ end
@@ -112,44 +112,6 @@ module Admin
112
112
  end
113
113
  end
114
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
- success, errors = DocumentDistribution.import(params.dig(:document_distribution, :distributions, :file))
129
- if success == true
130
- logger.debug("Distributions were created successfully.")
131
- if params[:document_id]
132
- redirect_to admin_document_document_distributions_path(@document), notice: "Distributions were created successfully."
133
- else
134
- redirect_to admin_document_distributions_path, notice: "Distributions were created successfully."
135
- end
136
- else
137
- logger.debug("Some distributions could not be created. #{errors.join(", ")}")
138
- if params[:document_id]
139
- redirect_to admin_document_document_distributions_path(@document), notice: "Some distributions could not be created. #{errors.join(", ")}"
140
- else
141
- redirect_to admin_document_distributions_path, notice: "Some distributions could not be created. #{errors.join(", ")}"
142
- end
143
- end
144
- rescue => e
145
- logger.debug("Distributions could not be created. #{e}")
146
- if params[:document_id]
147
- redirect_to admin_document_document_distributions_path(@document), notice: "Distributions could not be created. #{e}"
148
- else
149
- redirect_to admin_document_distributions_path, notice: "Distributions could not be created. #{e}"
150
- end
151
- end
152
-
153
115
  private
154
116
 
155
117
  # Sets the document based on the document_id parameter.
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Admin::ImportDistributionsController
4
+ #
5
+ # This controller handles the CRUD operations for ImportDistribution objects within the admin namespace.
6
+ # It provides actions to list, show, create, update, and delete import distributions, as well as run an import distribution.
7
+ #
8
+ # Before Actions:
9
+ # - set_import_distribution: Sets the @import_distribution instance variable for actions that require an import distribution ID.
10
+ #
11
+ # Actions:
12
+ # - index: Lists all imports with pagination.
13
+ # - show: Displays a specific import and its associated documents, with pagination for success and failed states.
14
+ # - new: Initializes a new Import object.
15
+ # - edit: Prepares an existing Import object for editing.
16
+ # - create: Creates a new Import object and redirects to import mappings if successful.
17
+ # - update: Updates an existing Import object and redirects to the import if successful.
18
+ # - destroy: Deletes an Import object and redirects to the imports list.
19
+ # - run: Executes the import process and redirects to the import show page.
20
+ #
21
+ # Private Methods:
22
+ # - set_import: Finds and sets the import based on the provided ID.
23
+ # - permittable_params: Returns an array of permitted parameters for import.
24
+ # - import_params: Permits parameters for creating or updating an import, including nested attributes.
25
+ module Admin
26
+ class ImportDistributionsController < Admin::AdminController
27
+ before_action :set_import_distribution, only: %i[show edit update destroy run]
28
+
29
+ # GET /import_distributions
30
+ # GET /import_distributions.json
31
+ # Lists all import distributions with pagination.
32
+ def index
33
+ @pagy, @import_distributions = pagy(ImportDistribution.all.order("created_at DESC"), items: 20)
34
+ end
35
+
36
+ # GET /import_distributions/1
37
+ # GET /import_distributions/1.json
38
+ # Displays a specific import distribution and its associated documents, with pagination for success and failed states.
39
+ def show
40
+ @pagy_failed, @import_failed_distributions = pagy(@import_distribution.import_document_distributions.not_in_state(:success), items: 50, page_param: :failed_page)
41
+ @pagy_success, @import_success_distributions = pagy(@import_distribution.import_document_distributions.in_state(:success), items: 50, page_param: :success_page)
42
+ end
43
+
44
+ # GET /import_distributions/new
45
+ # Initializes a new ImportDistribution object.
46
+ def new
47
+ @import_distribution = ImportDistribution.new
48
+ end
49
+
50
+ # GET /import_distributions/1/edit
51
+ # Prepares an existing ImportDistribution object for editing.
52
+ def edit
53
+ end
54
+
55
+ # POST /import_distributions
56
+ # POST /import_distributions.json
57
+ # Creates a new ImportDistribution object
58
+ def create
59
+ @import_distribution = ImportDistribution.new(import_distribution_params)
60
+
61
+ respond_to do |format|
62
+ if @import_distribution.save
63
+ format.html do
64
+ redirect_to admin_import_distribution_path(@import_distribution),
65
+ notice: "Import distribution was successful."
66
+ end
67
+ format.json { render :show, status: :created, location: @import_distribution }
68
+ else
69
+ format.html { render :new, status: :unprocessable_entity }
70
+ format.json { render json: @import_distribution.errors, status: :unprocessable_entity }
71
+ end
72
+ end
73
+ end
74
+
75
+ # PATCH/PUT /import_distributions/1
76
+ # PATCH/PUT /import_distributions/1.json
77
+ # Updates an existing ImportDistribution object and redirects to the import distribution if successful.
78
+ def update
79
+ respond_to do |format|
80
+ if @import_distribution.update(import_distribution_params)
81
+ format.html { redirect_to admin_import_distribution_path(@import_distribution), notice: "Import distribution was successfully updated." }
82
+ format.json { render :show, status: :ok, location: @import_distribution }
83
+ else
84
+ format.html { render :edit, status: :unprocessable_entity }
85
+ format.json { render json: @import_distribution.errors, status: :unprocessable_entity }
86
+ end
87
+ end
88
+ end
89
+
90
+ # DELETE /import_distributions/1
91
+ # DELETE /import_distributions/1.json
92
+ # Deletes an ImportDistribution object and redirects to the import distributions list.
93
+ def destroy
94
+ @import_distribution.destroy
95
+ respond_to do |format|
96
+ format.html { redirect_to admin_import_distributions_url, notice: "Import distribution was successfully destroyed." }
97
+ format.json { head :no_content }
98
+ end
99
+ end
100
+
101
+ # Runs the import process and redirects to the import show page.
102
+ def run
103
+ @import_distribution.run!
104
+ redirect_to admin_import_distribution_url(@import_distribution), notice: "Import distribution is running. Check back soon for results."
105
+ end
106
+
107
+ private
108
+
109
+ # Use callbacks to share common setup or constraints between actions.
110
+ # Finds and sets the import distribution based on the provided ID.
111
+ def set_import_distribution
112
+ @import_distribution = ImportDistribution.find(params[:id])
113
+ end
114
+
115
+ # Returns an array of permitted parameters for import distribution.
116
+ def permittable_params
117
+ %i[name filename source description row_count encoding content_type extension validity validation_result
118
+ csv_file run]
119
+ end
120
+
121
+ # Permits parameters for creating or updating an import distribution, including nested attributes.
122
+ def import_distribution_params
123
+ params.require(:import_distribution).permit(permittable_params)
124
+ end
125
+ end
126
+ end