bulkrax 9.3.4 → 9.4.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 +11 -1
- data/app/assets/javascripts/bulkrax/application.js +2 -1
- data/app/assets/javascripts/bulkrax/bulkrax.js +13 -4
- data/app/assets/javascripts/bulkrax/bulkrax_utils.js +96 -0
- data/app/assets/javascripts/bulkrax/datatables.js +1 -0
- data/app/assets/javascripts/bulkrax/entries.js +17 -10
- data/app/assets/javascripts/bulkrax/importers.js.erb +9 -2
- data/app/assets/javascripts/bulkrax/importers_stepper.js +2420 -0
- data/app/assets/stylesheets/bulkrax/application.css +1 -1
- data/app/assets/stylesheets/bulkrax/import_export.scss +9 -2
- data/app/assets/stylesheets/bulkrax/stepper/_header.scss +83 -0
- data/app/assets/stylesheets/bulkrax/stepper/_mixins.scss +26 -0
- data/app/assets/stylesheets/bulkrax/stepper/_navigation.scss +103 -0
- data/app/assets/stylesheets/bulkrax/stepper/_responsive.scss +46 -0
- data/app/assets/stylesheets/bulkrax/stepper/_review.scss +92 -0
- data/app/assets/stylesheets/bulkrax/stepper/_settings.scss +106 -0
- data/app/assets/stylesheets/bulkrax/stepper/_success.scss +26 -0
- data/app/assets/stylesheets/bulkrax/stepper/_summary.scss +171 -0
- data/app/assets/stylesheets/bulkrax/stepper/_upload.scss +339 -0
- data/app/assets/stylesheets/bulkrax/stepper/_validation.scss +237 -0
- data/app/assets/stylesheets/bulkrax/stepper/_variables.scss +46 -0
- data/app/assets/stylesheets/bulkrax/stepper.scss +32 -0
- data/app/controllers/bulkrax/guided_imports_controller.rb +175 -0
- data/app/controllers/bulkrax/importers_controller.rb +34 -28
- data/app/controllers/concerns/bulkrax/guided_import_demo_scenarios.rb +201 -0
- data/app/controllers/concerns/bulkrax/importer_file_handler.rb +217 -0
- data/app/factories/bulkrax/object_factory.rb +3 -2
- data/app/factories/bulkrax/valkyrie_object_factory.rb +61 -17
- data/app/jobs/bulkrax/export_work_job.rb +1 -3
- data/app/jobs/bulkrax/importer_job.rb +11 -4
- data/app/models/bulkrax/csv_entry.rb +27 -7
- data/app/models/bulkrax/entry.rb +4 -0
- data/app/models/bulkrax/importer.rb +31 -1
- data/app/models/concerns/bulkrax/has_matchers.rb +2 -2
- data/app/models/concerns/bulkrax/importer_exporter_behavior.rb +6 -5
- data/app/parsers/bulkrax/application_parser.rb +31 -5
- data/app/parsers/bulkrax/csv_parser.rb +42 -10
- data/app/parsers/concerns/bulkrax/csv_parser/csv_template_generation.rb +73 -0
- data/app/parsers/concerns/bulkrax/csv_parser/csv_validation.rb +133 -0
- data/app/parsers/concerns/bulkrax/csv_parser/csv_validation_helpers.rb +282 -0
- data/app/parsers/concerns/bulkrax/csv_parser/csv_validation_hierarchy.rb +96 -0
- data/app/services/bulkrax/csv_template/column_builder.rb +60 -0
- data/app/services/bulkrax/csv_template/column_descriptor.rb +58 -0
- data/app/services/bulkrax/csv_template/csv_builder.rb +83 -0
- data/app/services/bulkrax/csv_template/explanation_builder.rb +57 -0
- data/app/services/bulkrax/csv_template/field_analyzer.rb +56 -0
- data/app/services/bulkrax/csv_template/file_path_generator.rb +47 -0
- data/app/services/bulkrax/csv_template/file_validator.rb +68 -0
- data/app/services/bulkrax/csv_template/mapping_manager.rb +55 -0
- data/app/services/bulkrax/csv_template/model_loader.rb +50 -0
- data/app/services/bulkrax/csv_template/row_builder.rb +35 -0
- data/app/services/bulkrax/csv_template/schema_analyzer.rb +70 -0
- data/app/services/bulkrax/csv_template/split_formatter.rb +44 -0
- data/app/services/bulkrax/csv_template/value_determiner.rb +68 -0
- data/app/services/bulkrax/stepper_response_formatter.rb +347 -0
- data/app/services/bulkrax/validation_error_csv_builder.rb +99 -0
- data/app/validators/bulkrax/csv_row/child_reference.rb +56 -0
- data/app/validators/bulkrax/csv_row/circular_reference.rb +71 -0
- data/app/validators/bulkrax/csv_row/controlled_vocabulary.rb +74 -0
- data/app/validators/bulkrax/csv_row/duplicate_identifier.rb +63 -0
- data/app/validators/bulkrax/csv_row/missing_source_identifier.rb +31 -0
- data/app/validators/bulkrax/csv_row/parent_reference.rb +59 -0
- data/app/validators/bulkrax/csv_row/required_values.rb +64 -0
- data/app/views/bulkrax/entries/_parsed_metadata.html.erb +1 -1
- data/app/views/bulkrax/entries/_raw_metadata.html.erb +1 -1
- data/app/views/bulkrax/entries/show.html.erb +6 -6
- data/app/views/bulkrax/exporters/_form.html.erb +19 -43
- data/app/views/bulkrax/exporters/edit.html.erb +2 -2
- data/app/views/bulkrax/exporters/index.html.erb +5 -5
- data/app/views/bulkrax/exporters/new.html.erb +3 -5
- data/app/views/bulkrax/exporters/show.html.erb +3 -3
- data/app/views/bulkrax/guided_imports/new.html.erb +567 -0
- data/app/views/bulkrax/importers/_bagit_fields.html.erb +9 -9
- data/app/views/bulkrax/importers/_browse_everything.html.erb +1 -1
- data/app/views/bulkrax/importers/_csv_fields.html.erb +11 -11
- data/app/views/bulkrax/importers/_edit_form_buttons.html.erb +23 -23
- data/app/views/bulkrax/importers/_edit_item_buttons.html.erb +2 -2
- data/app/views/bulkrax/importers/_file_uploader.html.erb +3 -3
- data/app/views/bulkrax/importers/_form.html.erb +4 -5
- data/app/views/bulkrax/importers/_oai_fields.html.erb +8 -18
- data/app/views/bulkrax/importers/_xml_fields.html.erb +13 -13
- data/app/views/bulkrax/importers/edit.html.erb +2 -2
- data/app/views/bulkrax/importers/index.html.erb +19 -14
- data/app/views/bulkrax/importers/new.html.erb +10 -9
- data/app/views/bulkrax/importers/show.html.erb +23 -7
- data/app/views/bulkrax/importers/upload_corrected_entries.html.erb +6 -6
- data/app/views/bulkrax/shared/_bulkrax_errors.html.erb +11 -11
- data/app/views/bulkrax/shared/_bulkrax_field_mapping.html.erb +3 -3
- data/config/i18n-tasks.yml +195 -0
- data/config/locales/bulkrax.de.yml +504 -0
- data/config/locales/bulkrax.en.yml +487 -28
- data/config/locales/bulkrax.es.yml +504 -0
- data/config/locales/bulkrax.fr.yml +504 -0
- data/config/locales/bulkrax.it.yml +504 -0
- data/config/locales/bulkrax.pt-BR.yml +504 -0
- data/config/locales/bulkrax.zh.yml +503 -0
- data/config/routes.rb +10 -0
- data/lib/bulkrax/data/demo_scenarios.json +2235 -0
- data/lib/bulkrax/version.rb +1 -1
- data/lib/bulkrax.rb +31 -3
- data/lib/tasks/bulkrax_tasks.rake +0 -102
- metadata +55 -3
- /data/{app/services → lib}/wings/custom_queries/find_by_source_identifier.rb +0 -0
|
@@ -0,0 +1,567 @@
|
|
|
1
|
+
<% provide :page_header do %>
|
|
2
|
+
<h1><span class="fa fa-cloud-upload" aria-hidden="true"></span> <%= t('bulkrax.importer.guided_import.page_title') %></h1>
|
|
3
|
+
<p><%= t('bulkrax.importer.guided_import.page_subtitle') %></p>
|
|
4
|
+
<p>
|
|
5
|
+
<%= link_to t('bulkrax.importer.guided_import.feedback_link'), 'https://github.com/samvera/bulkrax/issues/new?template=guided_import_bug_report.md', target: '_blank', rel: 'noopener noreferrer', class: 'feedback-link' %>
|
|
6
|
+
</p>
|
|
7
|
+
<% end %>
|
|
8
|
+
|
|
9
|
+
<% content_for(:head) do %>
|
|
10
|
+
<meta name="turbolinks-cache-control" content="no-cache">
|
|
11
|
+
<% end %>
|
|
12
|
+
|
|
13
|
+
<script>
|
|
14
|
+
window.BulkraxI18n = <%= raw I18n.t('bulkrax.importer.guided_import.js').to_json %>;
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<div class="bulk-import-stepper-container" data-max-file-size="<%= (defined?(Hyrax) && Hyrax.config.uploader&.[](:maxFileSize)) || 524288000 %>">
|
|
18
|
+
<div class="stepper-wrapper">
|
|
19
|
+
|
|
20
|
+
<!-- Stepper Header -->
|
|
21
|
+
<div class="stepper-header d-flex align-items-center justify-content-center">
|
|
22
|
+
<div class="step-item d-flex flex-column align-items-center" data-step="1">
|
|
23
|
+
<div class="step-circle d-flex align-items-center justify-content-center">
|
|
24
|
+
<span class="fa fa-cloud-upload" aria-hidden="true"></span>
|
|
25
|
+
<span class="step-check fa fa-check" aria-hidden="true"></span>
|
|
26
|
+
</div>
|
|
27
|
+
<span class="step-label"><%= t('bulkrax.importer.guided_import.steps.upload_validate') %></span>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="step-connector"></div>
|
|
30
|
+
<div class="step-item d-flex flex-column align-items-center" data-step="2">
|
|
31
|
+
<div class="step-circle d-flex align-items-center justify-content-center">
|
|
32
|
+
<span class="fa fa-cog" aria-hidden="true"></span>
|
|
33
|
+
<span class="step-check fa fa-check" aria-hidden="true"></span>
|
|
34
|
+
</div>
|
|
35
|
+
<span class="step-label"><%= t('bulkrax.importer.guided_import.steps.configure_settings') %></span>
|
|
36
|
+
</div>
|
|
37
|
+
<div class="step-connector"></div>
|
|
38
|
+
<div class="step-item d-flex flex-column align-items-center" data-step="3">
|
|
39
|
+
<div class="step-circle d-flex align-items-center justify-content-center">
|
|
40
|
+
<span class="fa fa-play" aria-hidden="true"></span>
|
|
41
|
+
<span class="step-check fa fa-check" aria-hidden="true"></span>
|
|
42
|
+
</div>
|
|
43
|
+
<span class="step-label"><%= t('bulkrax.importer.guided_import.steps.review_start') %></span>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<!-- Success State (Hidden by default) -->
|
|
48
|
+
<div class="import-success-state" style="display: none;">
|
|
49
|
+
<div class="success-card text-center">
|
|
50
|
+
<div class="success-icon d-flex align-items-center justify-content-center">
|
|
51
|
+
<span class="fa fa-check-circle" aria-hidden="true"></span>
|
|
52
|
+
</div>
|
|
53
|
+
<h2><%= t('bulkrax.importer.guided_import.success.title') %></h2>
|
|
54
|
+
<p><%= t('bulkrax.importer.guided_import.success.message') %></p>
|
|
55
|
+
<div class="success-actions d-flex justify-content-center">
|
|
56
|
+
<a href="<%= importers_path %>" class="btn btn-secondary"><%= t('bulkrax.importer.guided_import.success.view_queue') %></a>
|
|
57
|
+
<button type="button" class="btn btn-primary" id="start-another-import"><%= t('bulkrax.importer.guided_import.success.start_another') %></button>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<!-- Main Form -->
|
|
63
|
+
<div class="stepper-content-wrapper">
|
|
64
|
+
<%= form_for [:bulkrax, Bulkrax::Importer.new], url: guided_import_create_path, method: :post, html: { id: 'bulk-import-stepper-form', multipart: true } do |f| %>
|
|
65
|
+
<%= hidden_field_tag 'locale', I18n.locale %>
|
|
66
|
+
<!-- ====== STEP 1: Upload & Validate ====== -->
|
|
67
|
+
<div class="step-content" data-step="1">
|
|
68
|
+
<div class="step-title">
|
|
69
|
+
<h2 tabindex="-1"><%= t('bulkrax.importer.guided_import.step1.title') %> <span class="text-danger">*</span></h2>
|
|
70
|
+
<p class="text-muted"><%= t('bulkrax.importer.guided_import.step1.description_html').html_safe %></p>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<!-- Upload Area -->
|
|
74
|
+
<div class="upload-zone-wrapper">
|
|
75
|
+
<!-- Upload Mode Tabs -->
|
|
76
|
+
<div class="upload-mode-tabs" role="tablist">
|
|
77
|
+
<button
|
|
78
|
+
type="button"
|
|
79
|
+
class="upload-mode-tab active"
|
|
80
|
+
data-upload-mode="upload"
|
|
81
|
+
role="tab"
|
|
82
|
+
aria-selected="true"
|
|
83
|
+
>
|
|
84
|
+
<span class="fa fa-cloud-upload" aria-hidden="true"></span> <%= t('bulkrax.importer.guided_import.step1.upload_files') %>
|
|
85
|
+
</button>
|
|
86
|
+
<button
|
|
87
|
+
type="button"
|
|
88
|
+
class="upload-mode-tab"
|
|
89
|
+
data-upload-mode="file_path"
|
|
90
|
+
role="tab"
|
|
91
|
+
aria-selected="false"
|
|
92
|
+
>
|
|
93
|
+
<span class="fa fa-folder-open" aria-hidden="true"></span> <%= t('bulkrax.importer.guided_import.step1.import_path') %>
|
|
94
|
+
</button>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
<!-- Empty State -->
|
|
98
|
+
<div class="upload-zone-empty">
|
|
99
|
+
<label
|
|
100
|
+
for="file-input"
|
|
101
|
+
class="upload-dropzone"
|
|
102
|
+
role="button"
|
|
103
|
+
tabindex="0"
|
|
104
|
+
aria-describedby="dropzone-hint"
|
|
105
|
+
>
|
|
106
|
+
<div class="upload-icon">
|
|
107
|
+
<span class="fa fa-cloud-upload" aria-hidden="true"></span>
|
|
108
|
+
</div>
|
|
109
|
+
<p><%= t('bulkrax.importer.guided_import.step1.dropzone_main_html').html_safe %></p>
|
|
110
|
+
<p class="text-muted small" id="dropzone-hint">
|
|
111
|
+
<%= t('bulkrax.importer.guided_import.step1.dropzone_hint') %>
|
|
112
|
+
</p>
|
|
113
|
+
<div class="upload-accepted-types">
|
|
114
|
+
<p class="text-muted small">
|
|
115
|
+
<span class="fa fa-file-text-o" aria-hidden="true"></span>
|
|
116
|
+
<%= t('bulkrax.importer.guided_import.step1.dropzone_csv_hint') %>
|
|
117
|
+
</p>
|
|
118
|
+
<p class="text-muted small">
|
|
119
|
+
<span class="fa fa-file-archive-o" aria-hidden="true"></span>
|
|
120
|
+
<%= t('bulkrax.importer.guided_import.step1.dropzone_zip_hint') %>
|
|
121
|
+
</p>
|
|
122
|
+
</div>
|
|
123
|
+
</label>
|
|
124
|
+
<input
|
|
125
|
+
type="file"
|
|
126
|
+
id="file-input"
|
|
127
|
+
name="importer[parser_fields][files][]"
|
|
128
|
+
accept=".csv,.zip"
|
|
129
|
+
multiple
|
|
130
|
+
class="sr-only"
|
|
131
|
+
aria-label="<%= t('bulkrax.importer.guided_import.step1.upload_files') %>"
|
|
132
|
+
>
|
|
133
|
+
|
|
134
|
+
<!-- Demo Scenarios (for testing) -->
|
|
135
|
+
<% if Bulkrax.config.guided_import_demo_scenarios_enabled %>
|
|
136
|
+
<div class="demo-scenarios" style="display: none;">
|
|
137
|
+
<p class="small text-primary"><strong>Demo: Pick a validation scenario</strong></p>
|
|
138
|
+
<div style="margin-bottom: 10px;">
|
|
139
|
+
<p class="small text-muted mb-1"><strong>✓ Success</strong></p>
|
|
140
|
+
<button type="button" class="btn btn-sm btn-outline-success btn-block scenario-btn" data-scenario="success_no_issues">CSV with Nested Collections and Works</button>
|
|
141
|
+
<button type="button" class="btn btn-sm btn-outline-success btn-block scenario-btn" data-scenario="success_with_files">CSV and ZIP</button>
|
|
142
|
+
<button type="button" class="btn btn-sm btn-outline-success btn-block scenario-btn" data-scenario="success_multi_parent">Multi-parent works</button>
|
|
143
|
+
<button type="button" class="btn btn-sm btn-outline-success btn-block scenario-btn" data-scenario="success_children_ids">Children IDs define hierarchy</button>
|
|
144
|
+
<button type="button" class="btn btn-sm btn-outline-success btn-block scenario-btn" data-scenario="success_with_mixed_hierarchy">Each collection defines hierarchy differently</button>
|
|
145
|
+
</div>
|
|
146
|
+
<div style="margin-bottom: 10px;">
|
|
147
|
+
<p class="small text-muted mb-1"><strong>⚠ Warnings</strong></p>
|
|
148
|
+
<button type="button" class="btn btn-sm btn-outline-warning btn-block scenario-btn" data-scenario="warning_unrecognized">Unrecognized fields</button>
|
|
149
|
+
<button type="button" class="btn btn-sm btn-outline-warning btn-block scenario-btn" data-scenario="warning_missing_files">Missing files from ZIP</button>
|
|
150
|
+
<button type="button" class="btn btn-sm btn-outline-warning btn-block scenario-btn" data-scenario="warning_no_zip">Files referenced, no ZIP</button>
|
|
151
|
+
<button type="button" class="btn btn-sm btn-outline-warning btn-block scenario-btn" data-scenario="warning_combined">Combined warnings</button>
|
|
152
|
+
</div>
|
|
153
|
+
<div>
|
|
154
|
+
<p class="small text-muted mb-1"><strong>✗ Errors</strong></p>
|
|
155
|
+
<button type="button" class="btn btn-sm btn-outline-danger btn-block scenario-btn" data-scenario="error_missing_required">Missing required fields</button>
|
|
156
|
+
<button type="button" class="btn btn-sm btn-outline-danger btn-block scenario-btn" data-scenario="error_combined">Errors + warnings</button>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
<% end %>
|
|
160
|
+
</div>
|
|
161
|
+
|
|
162
|
+
<!-- Files Uploaded State (hidden initially) -->
|
|
163
|
+
<div class="uploaded-files-container" style="display: none;">
|
|
164
|
+
<div class="uploaded-files-list">
|
|
165
|
+
<!-- File rows will be dynamically added here -->
|
|
166
|
+
</div>
|
|
167
|
+
<div class="upload-info-message">
|
|
168
|
+
<!-- Info messages will be added here based on upload state -->
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
|
|
172
|
+
<!-- Add another file dropzone (shown when 1 file uploaded) -->
|
|
173
|
+
<div class="add-another-dropzone" style="display: none;">
|
|
174
|
+
<label
|
|
175
|
+
for="file-input-additional"
|
|
176
|
+
class="upload-dropzone-small"
|
|
177
|
+
role="button"
|
|
178
|
+
tabindex="0"
|
|
179
|
+
aria-describedby="add-another-hint"
|
|
180
|
+
>
|
|
181
|
+
<div class="upload-icon">
|
|
182
|
+
<span class="fa fa-cloud-upload" aria-hidden="true"></span>
|
|
183
|
+
</div>
|
|
184
|
+
<p><%= t('bulkrax.importer.guided_import.step1.add_another') %></p>
|
|
185
|
+
<p class="text-muted small" id="add-another-hint">
|
|
186
|
+
<%= t('bulkrax.importer.guided_import.step1.add_another_hint_html').html_safe %>
|
|
187
|
+
</p>
|
|
188
|
+
<div class="upload-accepted-types">
|
|
189
|
+
<p class="text-muted small">
|
|
190
|
+
<span class="fa fa-file-text-o" aria-hidden="true"></span>
|
|
191
|
+
<%= t('bulkrax.importer.guided_import.step1.dropzone_csv_hint') %>
|
|
192
|
+
</p>
|
|
193
|
+
<p class="text-muted small">
|
|
194
|
+
<span class="fa fa-file-archive-o" aria-hidden="true"></span>
|
|
195
|
+
<%= t('bulkrax.importer.guided_import.step1.dropzone_zip_hint') %>
|
|
196
|
+
</p>
|
|
197
|
+
</div>
|
|
198
|
+
</label>
|
|
199
|
+
<input
|
|
200
|
+
type="file"
|
|
201
|
+
id="file-input-additional"
|
|
202
|
+
name="importer[parser_fields][files][]"
|
|
203
|
+
accept=".csv,.zip"
|
|
204
|
+
multiple
|
|
205
|
+
class="sr-only"
|
|
206
|
+
aria-label="<%= t('bulkrax.importer.guided_import.step1.add_another') %>"
|
|
207
|
+
>
|
|
208
|
+
</div>
|
|
209
|
+
|
|
210
|
+
<!-- File Path Input (hidden by default) -->
|
|
211
|
+
<div class="file-path-panel" style="display: none;">
|
|
212
|
+
<div class="file-path-input-wrapper">
|
|
213
|
+
<div class="upload-icon">
|
|
214
|
+
<span class="fa fa-folder-open" aria-hidden="true"></span>
|
|
215
|
+
</div>
|
|
216
|
+
<label for="import-file-path" class="control-label">
|
|
217
|
+
<%= t('bulkrax.importer.guided_import.step1.file_path_label') %>
|
|
218
|
+
</label>
|
|
219
|
+
<p class="text-muted small"><%= t('bulkrax.importer.guided_import.step1.file_path_hint') %></p>
|
|
220
|
+
<input
|
|
221
|
+
type="text"
|
|
222
|
+
id="import-file-path"
|
|
223
|
+
name="importer[parser_fields][import_file_path]"
|
|
224
|
+
class="form-control"
|
|
225
|
+
placeholder="<%= t('bulkrax.importer.guided_import.step1.file_path_placeholder') %>"
|
|
226
|
+
>
|
|
227
|
+
<!-- Params require file_style attribute -->
|
|
228
|
+
<%= hidden_field_tag 'importer[parser_fields][file_style]', I18n.t('bulkrax.importer.xml.file_style.server_path') %>
|
|
229
|
+
</div>
|
|
230
|
+
</div>
|
|
231
|
+
|
|
232
|
+
</div>
|
|
233
|
+
|
|
234
|
+
<!-- File Upload Error Messages -->
|
|
235
|
+
<div id="file-upload-errors" class="file-upload-errors" aria-live="polite" style="display: none;"></div>
|
|
236
|
+
|
|
237
|
+
<!-- Admin Set -->
|
|
238
|
+
<div class="form-group">
|
|
239
|
+
<div class="step-title">
|
|
240
|
+
<%= f.label :admin_set_id, for: 'importer-admin-set', class: 'h2' do %>
|
|
241
|
+
<%= t('bulkrax.importer.guided_import.step1.admin_set') %> <span class="text-danger">*</span>
|
|
242
|
+
<% end %>
|
|
243
|
+
<p class="text-muted"><%= t('bulkrax.importer.guided_import.step1.admin_set_hint') %></p>
|
|
244
|
+
</div>
|
|
245
|
+
<% admin_sets = available_admin_sets %>
|
|
246
|
+
<% default_admin_set = admin_sets.find { |name, id| name.include?('Default') }&.last %>
|
|
247
|
+
<%= f.select :admin_set_id,
|
|
248
|
+
options_for_select([[t('bulkrax.importer.guided_import.step1.admin_set_prompt'), '']] + admin_sets, default_admin_set),
|
|
249
|
+
{},
|
|
250
|
+
{ id: 'importer-admin-set', class: 'form-control', required: true } %>
|
|
251
|
+
</div>
|
|
252
|
+
|
|
253
|
+
<!-- Download Template Link -->
|
|
254
|
+
<div class="download-template-link">
|
|
255
|
+
<span class="fa fa-download text-primary" aria-hidden="true"></span>
|
|
256
|
+
<a id="download-csv-template-link" href="<%= sample_csv_file_importers_path %>" class="text-primary" download data-sample-csv-url="<%= sample_csv_file_importers_path %>"><%= t('bulkrax.importer.guided_import.step1.download_template') %></a>
|
|
257
|
+
</div>
|
|
258
|
+
|
|
259
|
+
<!-- Validate Button (tab-scoped: only one is visible at a time) -->
|
|
260
|
+
<button type="button" id="validate-upload-btn" class="validate-btn btn btn-primary btn-block btn-lg" disabled>
|
|
261
|
+
<span class="fa fa-file-text" aria-hidden="true"></span> <%= t('bulkrax.importer.guided_import.step1.validate_upload') %>
|
|
262
|
+
</button>
|
|
263
|
+
<button type="button" id="validate-path-btn" class="validate-btn btn btn-primary btn-block btn-lg" style="display: none;" disabled>
|
|
264
|
+
<span class="fa fa-file-text" aria-hidden="true"></span> <%= t('bulkrax.importer.guided_import.step1.validate_path') %>
|
|
265
|
+
</button>
|
|
266
|
+
|
|
267
|
+
<!-- Validation Results (hidden initially) -->
|
|
268
|
+
<div class="validation-results" aria-live="polite" style="display: none;">
|
|
269
|
+
|
|
270
|
+
<!-- Validation Status Accordion -->
|
|
271
|
+
<div class="accordion-wrapper">
|
|
272
|
+
<!-- Validation accordions will be added by JS -->
|
|
273
|
+
</div>
|
|
274
|
+
|
|
275
|
+
<!-- Import Size Gauge -->
|
|
276
|
+
<div class="import-size-gauge">
|
|
277
|
+
<!-- Will be populated by JS -->
|
|
278
|
+
</div>
|
|
279
|
+
|
|
280
|
+
<!-- Import Summary -->
|
|
281
|
+
<div class="import-summary">
|
|
282
|
+
<h3><%= t('bulkrax.importer.guided_import.step1.import_summary') %></h3>
|
|
283
|
+
<div class="row">
|
|
284
|
+
<div class="col-sm-4">
|
|
285
|
+
<div class="summary-card summary-card-collections">
|
|
286
|
+
<div class="summary-number">0</div>
|
|
287
|
+
<div class="summary-label"><%= t('bulkrax.importer.guided_import.step1.collections') %></div>
|
|
288
|
+
</div>
|
|
289
|
+
</div>
|
|
290
|
+
<div class="col-sm-4">
|
|
291
|
+
<div class="summary-card summary-card-works">
|
|
292
|
+
<div class="summary-number">0</div>
|
|
293
|
+
<div class="summary-label"><%= t('bulkrax.importer.guided_import.step1.works') %></div>
|
|
294
|
+
</div>
|
|
295
|
+
</div>
|
|
296
|
+
<div class="col-sm-4">
|
|
297
|
+
<div class="summary-card summary-card-filesets">
|
|
298
|
+
<div class="summary-number">0</div>
|
|
299
|
+
<div class="summary-label"><%= t('bulkrax.importer.guided_import.step1.file_sets') %></div>
|
|
300
|
+
</div>
|
|
301
|
+
</div>
|
|
302
|
+
</div>
|
|
303
|
+
|
|
304
|
+
<!-- Collection/Work Trees -->
|
|
305
|
+
<div class="hierarchy-accordions">
|
|
306
|
+
<!-- Will be populated by JS -->
|
|
307
|
+
</div>
|
|
308
|
+
</div>
|
|
309
|
+
|
|
310
|
+
<!-- Warning Acknowledgment -->
|
|
311
|
+
<div class="warning-acknowledgment" style="display: none;">
|
|
312
|
+
<label class="acknowledgment-checkbox">
|
|
313
|
+
<input type="checkbox" id="warnings-acked">
|
|
314
|
+
<span><%= t('bulkrax.importer.guided_import.step1.warning_ack') %></span>
|
|
315
|
+
</label>
|
|
316
|
+
</div>
|
|
317
|
+
</div>
|
|
318
|
+
|
|
319
|
+
<!-- Step Navigation -->
|
|
320
|
+
<div class="step-navigation d-flex justify-content-between align-items-end">
|
|
321
|
+
<button type="button" class="btn btn-outline-danger start-over-nav-btn d-inline-flex align-items-center">
|
|
322
|
+
<span class="fa fa-refresh" aria-hidden="true"></span> <%= t('bulkrax.importer.guided_import.nav.clear_start_over') %>
|
|
323
|
+
</button>
|
|
324
|
+
<div class="step-nav-right d-flex flex-column align-items-end">
|
|
325
|
+
<label class="skip-validation-label" style="display: none">
|
|
326
|
+
<input type="checkbox" id="skip-validation-checkbox">
|
|
327
|
+
<span><%= t('bulkrax.importer.guided_import.nav.skip_validation') %></span>
|
|
328
|
+
</label>
|
|
329
|
+
<button type="button" class="btn btn-primary step-next-btn" data-next-step="2" disabled>
|
|
330
|
+
<%= t('bulkrax.importer.guided_import.nav.next_step') %> <span class="fa fa-arrow-right" aria-hidden="true"></span>
|
|
331
|
+
</button>
|
|
332
|
+
</div>
|
|
333
|
+
</div>
|
|
334
|
+
</div>
|
|
335
|
+
|
|
336
|
+
<!-- ====== STEP 2: Configure Settings ====== -->
|
|
337
|
+
<div class="step-content" data-step="2" style="display: none;">
|
|
338
|
+
<div class="step-title">
|
|
339
|
+
<h2 tabindex="-1"><%= t('bulkrax.importer.guided_import.step2.title') %></h2>
|
|
340
|
+
<p class="text-muted"><%= t('bulkrax.importer.guided_import.step2.description') %></p>
|
|
341
|
+
</div>
|
|
342
|
+
|
|
343
|
+
<div class="settings-form">
|
|
344
|
+
<!-- Import Name -->
|
|
345
|
+
<div class="form-group">
|
|
346
|
+
<%= f.label :name, t('bulkrax.importer.guided_import.step2.import_name'), class: 'control-label' do %>
|
|
347
|
+
<%= t('bulkrax.importer.guided_import.step2.import_name') %> <span class="text-danger">*</span>
|
|
348
|
+
<% end %>
|
|
349
|
+
<%= f.text_field :name, class: 'form-control', value: "#{t('bulkrax.importer.guided_import.step2.import_name_prefix')}#{Date.today.strftime('%m/%d/%Y')}", required: true %>
|
|
350
|
+
</div>
|
|
351
|
+
|
|
352
|
+
<!-- Default Visibility -->
|
|
353
|
+
<div class="form-group">
|
|
354
|
+
<fieldset>
|
|
355
|
+
<legend class="control-label"><%= t('bulkrax.importer.guided_import.step2.default_visibility') %> <span class="text-danger">*</span></legend>
|
|
356
|
+
<p class="text-muted small"><%= t('bulkrax.importer.guided_import.step2.visibility_hint') %></p>
|
|
357
|
+
<div class="visibility-options row">
|
|
358
|
+
<div class="col-sm-4">
|
|
359
|
+
<div class="visibility-card" data-visibility="open">
|
|
360
|
+
<span class="fa fa-globe visibility-icon" aria-hidden="true"></span>
|
|
361
|
+
<label class="visibility-label" for="visibility_open"><%= t('bulkrax.importer.guided_import.step2.visibility_public') %>
|
|
362
|
+
<input
|
|
363
|
+
type="radio"
|
|
364
|
+
id="visibility_open"
|
|
365
|
+
name="importer[parser_fields][visibility]"
|
|
366
|
+
value="open"
|
|
367
|
+
checked class="sr-only"
|
|
368
|
+
>
|
|
369
|
+
</label>
|
|
370
|
+
<div class="visibility-desc"><%= t('bulkrax.importer.guided_import.step2.visibility_public_desc') %></div>
|
|
371
|
+
</div>
|
|
372
|
+
</div>
|
|
373
|
+
<div class="col-sm-4">
|
|
374
|
+
<div class="visibility-card" data-visibility="authenticated">
|
|
375
|
+
<span class="fa fa-users visibility-icon" aria-hidden="true"></span>
|
|
376
|
+
<label class="visibility-label" for="visibility_authenticated"><%= t('bulkrax.importer.guided_import.step2.visibility_institution') %>
|
|
377
|
+
<input
|
|
378
|
+
type="radio"
|
|
379
|
+
id="visibility_authenticated"
|
|
380
|
+
name="importer[parser_fields][visibility]"
|
|
381
|
+
value="authenticated"
|
|
382
|
+
class="sr-only"
|
|
383
|
+
>
|
|
384
|
+
</label>
|
|
385
|
+
<div class="visibility-desc"><%= t('bulkrax.importer.guided_import.step2.visibility_institution_desc') %></div>
|
|
386
|
+
</div>
|
|
387
|
+
</div>
|
|
388
|
+
<div class="col-sm-4">
|
|
389
|
+
<div class="visibility-card" data-visibility="restricted">
|
|
390
|
+
<span class="fa fa-lock visibility-icon" aria-hidden="true"></span>
|
|
391
|
+
<label class="visibility-label" for="visibility_restricted"><%= t('bulkrax.importer.guided_import.step2.visibility_private') %>
|
|
392
|
+
<input
|
|
393
|
+
type="radio"
|
|
394
|
+
id="visibility_restricted"
|
|
395
|
+
name="importer[parser_fields][visibility]"
|
|
396
|
+
value="restricted"
|
|
397
|
+
class="sr-only"
|
|
398
|
+
>
|
|
399
|
+
</label>
|
|
400
|
+
<div class="visibility-desc"><%= t('bulkrax.importer.guided_import.step2.visibility_private_desc') %></div>
|
|
401
|
+
</div>
|
|
402
|
+
</div>
|
|
403
|
+
</div>
|
|
404
|
+
</fieldset>
|
|
405
|
+
</div>
|
|
406
|
+
|
|
407
|
+
<!-- Optional Settings -->
|
|
408
|
+
<div class="optional-settings-accordion">
|
|
409
|
+
<div class="card">
|
|
410
|
+
<div class="card-header" data-toggle="collapse" data-target="#optional-settings">
|
|
411
|
+
<h3 class="mb-0">
|
|
412
|
+
<button class="btn btn-link btn-block text-left" type="button">
|
|
413
|
+
<span>
|
|
414
|
+
<span class="fa fa-cog" aria-hidden="true"></span>
|
|
415
|
+
<%= t('bulkrax.importer.guided_import.step2.optional_settings') %>
|
|
416
|
+
</span>
|
|
417
|
+
<span class="fa fa-chevron-down" aria-hidden="true"></span>
|
|
418
|
+
</button>
|
|
419
|
+
</h3>
|
|
420
|
+
</div>
|
|
421
|
+
<div id="optional-settings" class="collapse">
|
|
422
|
+
<div class="card-body">
|
|
423
|
+
<div id="default-rights-required-alert" class="alert alert-info" style="display: none;" role="alert">
|
|
424
|
+
<%= t('bulkrax.importer.guided_import.step2.rights_required_alert_html').html_safe %>
|
|
425
|
+
</div>
|
|
426
|
+
<div id="default-rights-skipped-hint" class="alert alert-secondary" style="display: none;" role="status">
|
|
427
|
+
<%= t('bulkrax.importer.guided_import.step2.rights_skipped_hint_html').html_safe %>
|
|
428
|
+
</div>
|
|
429
|
+
<div class="form-group">
|
|
430
|
+
<label class="control-label default-rights-statement-label" for="importer_parser_fields_rights_statement"><%= t('bulkrax.importer.guided_import.step2.default_rights') %></label>
|
|
431
|
+
<% if defined?(::Hyrax) %>
|
|
432
|
+
<% rights_statements = Hyrax.config.rights_statement_service_class.new %>
|
|
433
|
+
<%= select_tag 'importer[parser_fields][rights_statement]',
|
|
434
|
+
options_for_select([[t('bulkrax.importer.guided_import.step2.rights_none'), '']] + rights_statements.select_active_options),
|
|
435
|
+
class: 'form-control' %>
|
|
436
|
+
<% else %>
|
|
437
|
+
<%= select_tag 'importer[parser_fields][rights_statement]',
|
|
438
|
+
options_for_select([[t('bulkrax.importer.guided_import.step2.rights_none'), '']]),
|
|
439
|
+
class: 'form-control' %>
|
|
440
|
+
<% end %>
|
|
441
|
+
</div>
|
|
442
|
+
<div class="form-group">
|
|
443
|
+
<div class="form-check">
|
|
444
|
+
<%= check_box_tag 'importer[parser_fields][override_rights_statement]', '1', false, class: 'form-check-input', id: 'importer_parser_fields_override_rights_statement' %>
|
|
445
|
+
<label class="form-check-label control-label" for="importer_parser_fields_override_rights_statement">
|
|
446
|
+
<%= t('simple_form.labels.defaults.override_rights_statement') %>
|
|
447
|
+
</label>
|
|
448
|
+
</div>
|
|
449
|
+
<small class="form-text text-muted"><%= t('bulkrax.importer.hints.override_rights_statement') %></small>
|
|
450
|
+
</div>
|
|
451
|
+
|
|
452
|
+
<div class="form-group">
|
|
453
|
+
<%= f.label :limit, t('bulkrax.importer.guided_import.step2.test_limit'), class: 'control-label' %>
|
|
454
|
+
<%= f.number_field :limit, class: 'form-control', placeholder: t('bulkrax.importer.guided_import.step2.test_limit_placeholder') %>
|
|
455
|
+
</div>
|
|
456
|
+
</div>
|
|
457
|
+
</div>
|
|
458
|
+
</div>
|
|
459
|
+
</div>
|
|
460
|
+
</div>
|
|
461
|
+
|
|
462
|
+
<!-- Step Navigation -->
|
|
463
|
+
<div class="step-navigation d-flex justify-content-between align-items-end">
|
|
464
|
+
<button type="button" class="btn btn-outline-danger start-over-nav-btn d-inline-flex align-items-center">
|
|
465
|
+
<span class="fa fa-refresh" aria-hidden="true"></span> <%= t('bulkrax.importer.guided_import.nav.clear_start_over') %>
|
|
466
|
+
</button>
|
|
467
|
+
<div class="d-flex align-items-end">
|
|
468
|
+
<button type="button" class="btn btn-secondary step-prev-btn" data-prev-step="1">
|
|
469
|
+
<span class="fa fa-arrow-left" aria-hidden="true"></span> <%= t('bulkrax.importer.guided_import.nav.back') %>
|
|
470
|
+
</button>
|
|
471
|
+
<button type="button" class="btn btn-primary step-next-btn" data-next-step="3" disabled>
|
|
472
|
+
<%= t('bulkrax.importer.guided_import.nav.next_step') %> <span class="fa fa-arrow-right" aria-hidden="true"></span>
|
|
473
|
+
</button>
|
|
474
|
+
</div>
|
|
475
|
+
</div>
|
|
476
|
+
</div>
|
|
477
|
+
|
|
478
|
+
<!-- ====== STEP 3: Review & Start ====== -->
|
|
479
|
+
<div class="step-content" data-step="3" style="display: none;">
|
|
480
|
+
<div class="step-title">
|
|
481
|
+
<h2 tabindex="-1"><%= t('bulkrax.importer.guided_import.step3.title') %></h2>
|
|
482
|
+
<p class="text-muted"><%= t('bulkrax.importer.guided_import.step3.description') %></p>
|
|
483
|
+
</div>
|
|
484
|
+
|
|
485
|
+
<!-- Large Import Warning -->
|
|
486
|
+
<div class="large-import-warning" style="display: none;">
|
|
487
|
+
<div class="alert alert-danger">
|
|
488
|
+
<span class="fa fa-exclamation-triangle" aria-hidden="true"></span>
|
|
489
|
+
<strong><%= t('bulkrax.importer.guided_import.step3.large_import_warning') %></strong>
|
|
490
|
+
<p><%= t('bulkrax.importer.guided_import.step3.large_import_message_html', count: 0).html_safe %></p>
|
|
491
|
+
</div>
|
|
492
|
+
</div>
|
|
493
|
+
|
|
494
|
+
<!-- Review Summary -->
|
|
495
|
+
<div class="review-summary">
|
|
496
|
+
<div class="alert alert-success">
|
|
497
|
+
<div class="review-header">
|
|
498
|
+
<span class="fa fa-check-circle" aria-hidden="true"></span>
|
|
499
|
+
<h3><%= t('bulkrax.importer.guided_import.step3.ready_to_import') %></h3>
|
|
500
|
+
</div>
|
|
501
|
+
|
|
502
|
+
<div class="review-section">
|
|
503
|
+
<h4><%= t('bulkrax.importer.guided_import.step3.section_files') %></h4>
|
|
504
|
+
<div class="review-files">
|
|
505
|
+
<!-- Will be populated by JS -->
|
|
506
|
+
</div>
|
|
507
|
+
</div>
|
|
508
|
+
|
|
509
|
+
<div class="review-section">
|
|
510
|
+
<h4><%= t('bulkrax.importer.guided_import.step3.section_records') %></h4>
|
|
511
|
+
<div class="review-records">
|
|
512
|
+
<!-- Will be populated by JS -->
|
|
513
|
+
</div>
|
|
514
|
+
</div>
|
|
515
|
+
|
|
516
|
+
<div class="review-section">
|
|
517
|
+
<h4><%= t('bulkrax.importer.guided_import.step3.section_settings') %></h4>
|
|
518
|
+
<div class="review-settings">
|
|
519
|
+
<!-- Will be populated by JS -->
|
|
520
|
+
</div>
|
|
521
|
+
</div>
|
|
522
|
+
|
|
523
|
+
<div class="review-section review-warnings" style="display: none;">
|
|
524
|
+
<h4><%= t('bulkrax.importer.guided_import.step3.section_warnings') %></h4>
|
|
525
|
+
<div class="review-warnings-list">
|
|
526
|
+
<!-- Will be populated by JS -->
|
|
527
|
+
</div>
|
|
528
|
+
</div>
|
|
529
|
+
</div>
|
|
530
|
+
</div>
|
|
531
|
+
|
|
532
|
+
<p class="text-center text-muted small"><%= t('bulkrax.importer.guided_import.step3.background_note') %></p>
|
|
533
|
+
|
|
534
|
+
<!-- Step Navigation -->
|
|
535
|
+
<div class="step-navigation d-flex justify-content-between align-items-end">
|
|
536
|
+
<button type="button" class="btn btn-outline-danger start-over-nav-btn d-inline-flex align-items-center">
|
|
537
|
+
<span class="fa fa-refresh" aria-hidden="true"></span> <%= t('bulkrax.importer.guided_import.nav.clear_start_over') %>
|
|
538
|
+
</button>
|
|
539
|
+
<div class="d-flex align-items-end">
|
|
540
|
+
<button type="button" class="btn btn-secondary step-prev-btn" data-prev-step="2">
|
|
541
|
+
<span class="fa fa-arrow-left" aria-hidden="true"></span> <%= t('bulkrax.importer.guided_import.nav.back') %>
|
|
542
|
+
</button>
|
|
543
|
+
<button type="submit" class="btn btn-success" id="start-import-btn">
|
|
544
|
+
<%= t('bulkrax.importer.guided_import.nav.start_import') %>
|
|
545
|
+
</button>
|
|
546
|
+
</div>
|
|
547
|
+
</div>
|
|
548
|
+
</div>
|
|
549
|
+
|
|
550
|
+
<% end %>
|
|
551
|
+
</div>
|
|
552
|
+
</div>
|
|
553
|
+
</div>
|
|
554
|
+
|
|
555
|
+
<!-- Toast notifications (announced to screen readers) -->
|
|
556
|
+
<div id="upload-notifications" aria-live="polite"></div>
|
|
557
|
+
|
|
558
|
+
<!-- Hidden fields for storing state -->
|
|
559
|
+
<div id="stepper-state" style="display: none;"
|
|
560
|
+
data-current-step="1"
|
|
561
|
+
data-validated="false"
|
|
562
|
+
data-has-warnings="false"
|
|
563
|
+
data-warnings-acked="false"
|
|
564
|
+
data-upload-state="empty"
|
|
565
|
+
data-validation-data=""
|
|
566
|
+
data-demo-scenarios-enabled="<%= Bulkrax.config.guided_import_demo_scenarios_enabled %>">
|
|
567
|
+
</div>
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
|
|
18
18
|
<%= fi.input :visibility,
|
|
19
19
|
collection: [
|
|
20
|
-
['
|
|
21
|
-
['
|
|
22
|
-
['
|
|
20
|
+
[t('bulkrax.importer.bagit.visibility.public'), 'open'],
|
|
21
|
+
[t('bulkrax.importer.bagit.visibility.private'), 'restricted'],
|
|
22
|
+
[t('bulkrax.importer.bagit.visibility.institution'), 'authenticated']
|
|
23
23
|
],
|
|
24
24
|
selected: importer.parser_fields['visibility'] || 'open',
|
|
25
25
|
input_html: { class: 'form-control' }
|
|
@@ -35,15 +35,15 @@
|
|
|
35
35
|
input_html: { class: 'form-control' } ,
|
|
36
36
|
required: false
|
|
37
37
|
%>
|
|
38
|
-
<%= fi.input :override_rights_statement, as: :boolean, hint: '
|
|
38
|
+
<%= fi.input :override_rights_statement, as: :boolean, hint: t('bulkrax.importer.hints.override_rights_statement'), input_html: { checked: (importer.parser_fields['override_rights_statement'] == "1") } %>
|
|
39
39
|
<% end %>
|
|
40
|
-
<h4
|
|
41
|
-
<p
|
|
42
|
-
<p
|
|
40
|
+
<h4><%= t('bulkrax.importer.bagit.bags_to_import') %></h4>
|
|
41
|
+
<p><%= t('bulkrax.importer.bagit.file_upload_hint') %></p>
|
|
42
|
+
<p><%= t('bulkrax.importer.bagit.server_path_hint') %></p>
|
|
43
43
|
|
|
44
44
|
<%= fi.input :file_style,
|
|
45
|
-
collection: ['
|
|
46
|
-
(defined?(::Hyrax) && Hyrax.config.browse_everything? ? ['
|
|
45
|
+
collection: [t('bulkrax.importer.bagit.file_style.upload'), t('bulkrax.importer.bagit.file_style.server_path')] +
|
|
46
|
+
(defined?(::Hyrax) && Hyrax.config.browse_everything? ? [t('bulkrax.importer.bagit.file_style.cloud')] : []),
|
|
47
47
|
as: :radio_buttons, label: false %>
|
|
48
48
|
<div id='file_upload'>
|
|
49
49
|
<% if defined?(::Hyrax) %>
|
|
@@ -7,6 +7,6 @@
|
|
|
7
7
|
<button type="button" data-toggle="browse-everything" data-route="<%=browse_everything_engine.root_path%>"
|
|
8
8
|
data-target="#<%= f %>" class="btn btn-primary" id="browse">
|
|
9
9
|
<span class="fa fa-plus"></span>
|
|
10
|
-
|
|
10
|
+
<%= t('bulkrax.importer.browse_everything.add_cloud_files') %>
|
|
11
11
|
</button>
|
|
12
12
|
</div>
|