bulkrax 6.0.1 → 8.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +7 -7
- data/app/assets/javascripts/bulkrax/bulkrax.js +11 -0
- data/app/assets/javascripts/bulkrax/datatables.js +139 -0
- data/app/assets/javascripts/bulkrax/exporters.js +4 -4
- data/app/assets/javascripts/bulkrax/importers.js.erb +15 -1
- data/app/assets/stylesheets/bulkrax/import_export.scss +6 -1
- data/app/controllers/bulkrax/entries_controller.rb +52 -3
- data/app/controllers/bulkrax/exporters_controller.rb +20 -8
- data/app/controllers/bulkrax/importers_controller.rb +31 -12
- data/app/controllers/concerns/bulkrax/datatables_behavior.rb +201 -0
- data/app/factories/bulkrax/object_factory.rb +135 -163
- data/app/factories/bulkrax/object_factory_interface.rb +491 -0
- data/app/factories/bulkrax/valkyrie_object_factory.rb +402 -0
- data/app/helpers/bulkrax/application_helper.rb +7 -3
- data/app/helpers/bulkrax/importers_helper.rb +1 -1
- data/app/helpers/bulkrax/validation_helper.rb +4 -4
- data/app/jobs/bulkrax/create_relationships_job.rb +28 -17
- data/app/jobs/bulkrax/delete_and_import_collection_job.rb +8 -0
- data/app/jobs/bulkrax/delete_and_import_file_set_job.rb +8 -0
- data/app/jobs/bulkrax/delete_and_import_job.rb +20 -0
- data/app/jobs/bulkrax/delete_and_import_work_job.rb +8 -0
- data/app/jobs/bulkrax/delete_job.rb +8 -3
- data/app/jobs/bulkrax/download_cloud_file_job.rb +17 -4
- data/app/jobs/bulkrax/import_collection_job.rb +1 -1
- data/app/jobs/bulkrax/import_file_set_job.rb +6 -3
- data/app/jobs/bulkrax/import_job.rb +7 -0
- data/app/jobs/bulkrax/import_work_job.rb +1 -1
- data/app/jobs/bulkrax/importer_job.rb +19 -3
- data/app/matchers/bulkrax/application_matcher.rb +0 -2
- data/app/models/bulkrax/csv_collection_entry.rb +1 -3
- data/app/models/bulkrax/csv_entry.rb +9 -7
- data/app/models/bulkrax/entry.rb +9 -11
- data/app/models/bulkrax/exporter.rb +11 -4
- data/app/models/bulkrax/importer.rb +49 -10
- data/app/models/bulkrax/oai_entry.rb +0 -3
- data/app/models/bulkrax/oai_set_entry.rb +1 -3
- data/app/models/bulkrax/rdf_collection_entry.rb +1 -4
- data/app/models/bulkrax/rdf_entry.rb +70 -69
- data/app/models/bulkrax/status.rb +10 -1
- data/app/models/bulkrax/xml_entry.rb +0 -1
- data/app/models/concerns/bulkrax/dynamic_record_lookup.rb +2 -19
- data/app/models/concerns/bulkrax/export_behavior.rb +2 -2
- data/app/models/concerns/bulkrax/file_factory.rb +174 -118
- data/app/models/concerns/bulkrax/file_set_entry_behavior.rb +5 -3
- data/app/models/concerns/bulkrax/has_matchers.rb +28 -25
- data/app/models/concerns/bulkrax/import_behavior.rb +14 -33
- data/app/models/concerns/bulkrax/importer_exporter_behavior.rb +3 -2
- data/app/models/concerns/bulkrax/status_info.rb +8 -0
- data/app/parsers/bulkrax/application_parser.rb +116 -21
- data/app/parsers/bulkrax/bagit_parser.rb +173 -195
- data/app/parsers/bulkrax/csv_parser.rb +15 -57
- data/app/parsers/bulkrax/oai_dc_parser.rb +44 -16
- data/app/parsers/bulkrax/parser_export_record_set.rb +20 -24
- data/app/parsers/bulkrax/xml_parser.rb +18 -23
- data/app/services/bulkrax/factory_class_finder.rb +92 -0
- data/app/services/bulkrax/remove_relationships_for_importer.rb +3 -1
- data/app/services/hyrax/custom_queries/find_by_source_identifier.rb +50 -0
- data/app/services/wings/custom_queries/find_by_source_identifier.rb +32 -0
- data/app/views/bulkrax/entries/_parsed_metadata.html.erb +2 -2
- data/app/views/bulkrax/entries/_raw_metadata.html.erb +2 -2
- data/app/views/bulkrax/entries/show.html.erb +9 -8
- data/app/views/bulkrax/exporters/_form.html.erb +10 -10
- data/app/views/bulkrax/exporters/edit.html.erb +1 -1
- data/app/views/bulkrax/exporters/index.html.erb +13 -57
- data/app/views/bulkrax/exporters/new.html.erb +1 -1
- data/app/views/bulkrax/exporters/show.html.erb +6 -12
- data/app/views/bulkrax/importers/_browse_everything.html.erb +2 -2
- data/app/views/bulkrax/importers/_csv_fields.html.erb +8 -2
- data/app/views/bulkrax/importers/_edit_form_buttons.html.erb +8 -1
- data/app/views/bulkrax/importers/_edit_item_buttons.html.erb +18 -0
- data/app/views/bulkrax/importers/edit.html.erb +1 -1
- data/app/views/bulkrax/importers/index.html.erb +20 -64
- data/app/views/bulkrax/importers/new.html.erb +1 -1
- data/app/views/bulkrax/importers/show.html.erb +8 -14
- data/app/views/bulkrax/importers/upload_corrected_entries.html.erb +2 -2
- data/app/views/bulkrax/shared/_bulkrax_errors.html.erb +1 -1
- data/app/views/bulkrax/shared/_bulkrax_field_mapping.html.erb +1 -1
- data/app/views/bulkrax/shared/_entries_tab.html.erb +16 -0
- data/config/locales/bulkrax.en.yml +7 -0
- data/config/routes.rb +8 -2
- data/db/migrate/20230608153601_add_indices_to_bulkrax.rb +20 -9
- data/db/migrate/20240208005801_denormalize_status_message.rb +7 -0
- data/db/migrate/20240209070952_update_identifier_index.rb +6 -0
- data/db/migrate/20240307053156_add_index_to_metadata_bulkrax_identifier.rb +18 -0
- data/lib/bulkrax/engine.rb +23 -0
- data/lib/bulkrax/version.rb +1 -1
- data/lib/bulkrax.rb +107 -19
- data/lib/generators/bulkrax/templates/config/initializers/bulkrax.rb +2 -0
- data/lib/tasks/bulkrax_tasks.rake +13 -0
- data/lib/tasks/reset.rake +4 -4
- metadata +64 -8
- data/app/views/bulkrax/shared/_collection_entries_tab.html.erb +0 -39
- data/app/views/bulkrax/shared/_file_set_entries_tab.html.erb +0 -39
- data/app/views/bulkrax/shared/_work_entries_tab.html.erb +0 -39
@@ -33,13 +33,14 @@
|
|
33
33
|
|
34
34
|
<p class='bulkrax-p-align'>
|
35
35
|
<% if @importer.present? %>
|
36
|
+
<%# TODO Consider how to account for Bulkrax.collection_model_class %>
|
36
37
|
<% factory_record = @entry.factory.find %>
|
37
38
|
<% if factory_record.present? && @entry.factory_class %>
|
38
|
-
<strong><%= @entry.factory_class.
|
39
|
-
<% if @entry.factory_class.
|
40
|
-
<%= link_to @entry.factory_class.
|
39
|
+
<strong><%= @entry.factory_class.model_name.human %> Link:</strong>
|
40
|
+
<% if defined?(Hyrax) && @entry.factory_class.model_name.human == 'Collection' %>
|
41
|
+
<%= link_to @entry.factory_class.model_name.human, hyrax.polymorphic_path(factory_record) %>
|
41
42
|
<% else %>
|
42
|
-
<%= link_to @entry.factory_class.
|
43
|
+
<%= link_to @entry.factory_class.model_name.human, main_app.polymorphic_path(factory_record) %>
|
43
44
|
<% end %>
|
44
45
|
<% else %>
|
45
46
|
<strong>Item Link:</strong> Item has not yet been imported successfully
|
@@ -47,11 +48,11 @@
|
|
47
48
|
<% else %>
|
48
49
|
<% record = @entry&.hyrax_record %>
|
49
50
|
<% if record.present? && @entry.factory_class %>
|
50
|
-
<strong><%= record.
|
51
|
-
<% if defined?(
|
52
|
-
<%= link_to record.
|
51
|
+
<strong><%= record.model_name.human %> Link:</strong>
|
52
|
+
<% if defined?(Hyrax) && record.model_name.human == "Collection" %>
|
53
|
+
<%= link_to record.model_name.human, hyrax.polymorphic_path(record) %>
|
53
54
|
<% else %>
|
54
|
-
<%= link_to record.
|
55
|
+
<%= link_to record.model_name.human, main_app.polymorphic_path(record) %>
|
55
56
|
<% end %>
|
56
57
|
<% else %>
|
57
58
|
<strong>Item Link:</strong> No item associated with this entry or class unknown
|
@@ -33,8 +33,8 @@
|
|
33
33
|
label: t('bulkrax.exporter.labels.importer'),
|
34
34
|
required: true,
|
35
35
|
prompt: 'Select from the list',
|
36
|
-
label_html: { class: 'importer export-source-option d-none' },
|
37
|
-
input_html: { class: 'importer export-source-option d-none form-control' },
|
36
|
+
label_html: { class: 'importer export-source-option d-none hidden' },
|
37
|
+
input_html: { class: 'importer export-source-option d-none hidden form-control' },
|
38
38
|
collection: form.object.importers_list.sort %>
|
39
39
|
|
40
40
|
<%= form.input :export_source_collection,
|
@@ -42,9 +42,9 @@
|
|
42
42
|
label: t('bulkrax.exporter.labels.collection'),
|
43
43
|
required: true,
|
44
44
|
placeholder: @collection&.title&.first,
|
45
|
-
label_html: { class: 'collection export-source-option d-none' },
|
45
|
+
label_html: { class: 'collection export-source-option d-none hidden' },
|
46
46
|
input_html: {
|
47
|
-
class: 'collection export-source-option d-none form-control',
|
47
|
+
class: 'collection export-source-option d-none hidden form-control',
|
48
48
|
data: {
|
49
49
|
'autocomplete-url' => '/authorities/search/collections',
|
50
50
|
'autocomplete' => 'collection'
|
@@ -56,8 +56,8 @@
|
|
56
56
|
label: t('bulkrax.exporter.labels.worktype'),
|
57
57
|
required: true,
|
58
58
|
prompt: 'Select from the list',
|
59
|
-
label_html: { class: 'worktype export-source-option d-none' },
|
60
|
-
input_html: { class: 'worktype export-source-option d-none form-control' },
|
59
|
+
label_html: { class: 'worktype export-source-option d-none hidden' },
|
60
|
+
input_html: { class: 'worktype export-source-option d-none hidden form-control' },
|
61
61
|
collection: Bulkrax.curation_concerns.map { |cc| [cc.to_s, cc.to_s] } %>
|
62
62
|
|
63
63
|
<%= form.input :limit,
|
@@ -80,7 +80,7 @@
|
|
80
80
|
as: :boolean,
|
81
81
|
label: t('bulkrax.exporter.labels.filter_by_date') %>
|
82
82
|
|
83
|
-
<div id="date_filter_picker" class="d-none">
|
83
|
+
<div id="date_filter_picker" class="d-none hidden">
|
84
84
|
<%= form.input :start_date,
|
85
85
|
as: :date,
|
86
86
|
label: t('bulkrax.exporter.labels.start_date'),
|
@@ -136,13 +136,13 @@
|
|
136
136
|
// get the date filter option and show the corresponding date selectors
|
137
137
|
$('.exporter_date_filter').change(function () {
|
138
138
|
if ($('.exporter_date_filter').find(".boolean").is(":checked"))
|
139
|
-
$('#date_filter_picker').removeClass('d-none');
|
139
|
+
$('#date_filter_picker').removeClass('d-none hidden');
|
140
140
|
else
|
141
|
-
$('#date_filter_picker').addClass('d-none');
|
141
|
+
$('#date_filter_picker').addClass('d-none hidden');
|
142
142
|
});
|
143
143
|
|
144
144
|
if ($('.exporter_date_filter').find(".boolean").is(":checked"))
|
145
|
-
$('#date_filter_picker').removeClass('d-none');
|
145
|
+
$('#date_filter_picker').removeClass('d-none hidden');
|
146
146
|
});
|
147
147
|
});
|
148
148
|
</script>
|
@@ -14,7 +14,7 @@
|
|
14
14
|
<%= form.button :submit, value: 'Update and Re-Export All Items', class: 'btn btn-primary' %>
|
15
15
|
|
|
16
16
|
<% cancel_path = form.object.persisted? ? exporter_path(form.object) : exporters_path %>
|
17
|
-
<%= link_to t('.cancel'), cancel_path, class: 'btn btn-default ' %>
|
17
|
+
<%= link_to t('bulkrax.cancel'), cancel_path, class: 'btn btn-default ' %>
|
18
18
|
</div>
|
19
19
|
</div>
|
20
20
|
<% end %>
|
@@ -13,62 +13,18 @@
|
|
13
13
|
|
14
14
|
<div class="panel panel-default">
|
15
15
|
<div class="panel-body">
|
16
|
-
|
17
|
-
<
|
18
|
-
<
|
19
|
-
<
|
20
|
-
<
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
</thead>
|
30
|
-
<tbody>
|
31
|
-
<% @exporters.each do |exporter| %>
|
32
|
-
<tr>
|
33
|
-
<th scope="row"><%= link_to exporter.name, exporter_path(exporter) %></th>
|
34
|
-
<td><%= exporter.status %></td>
|
35
|
-
<td><%= exporter.created_at %></td>
|
36
|
-
<td>
|
37
|
-
<% if File.exist?(exporter.exporter_export_zip_path) %>
|
38
|
-
<%= simple_form_for(exporter, method: :get, url: exporter_download_path(exporter)) do |form| %>
|
39
|
-
<%= render 'downloads', exporter: exporter, form: form %>
|
40
|
-
<%= form.button :submit, value: 'Download', data: { disable_with: false } %>
|
41
|
-
<% end %>
|
42
|
-
<% end%>
|
43
|
-
</td>
|
44
|
-
<td><%= link_to raw('<span class="glyphicon glyphicon-info-sign"></span>'), exporter_path(exporter) %></td>
|
45
|
-
<td><%= link_to raw('<span class="glyphicon glyphicon-pencil"></span>'), edit_exporter_path(exporter), data: { turbolinks: false } %></td>
|
46
|
-
<td><%= link_to raw('<span class="glyphicon glyphicon-remove"></span>'), exporter, method: :delete, data: { confirm: 'Are you sure?' } %></td>
|
47
|
-
</tr>
|
48
|
-
<% end %>
|
49
|
-
</tbody>
|
50
|
-
</table>
|
51
|
-
</div>
|
52
|
-
<% else %>
|
53
|
-
<p>No exporters have been created.</p>
|
54
|
-
<% end %>
|
16
|
+
<div class="table-responsive">
|
17
|
+
<table id='exporters-table' class="table table-striped">
|
18
|
+
<thead>
|
19
|
+
<tr>
|
20
|
+
<th scope="col">Name</th>
|
21
|
+
<th scope="col">Status</th>
|
22
|
+
<th scope="col">Date Exported</th>
|
23
|
+
<th scope="col">Downloadable Files</th>
|
24
|
+
<th scope="col">Actions</th>
|
25
|
+
</tr>
|
26
|
+
</thead>
|
27
|
+
</table>
|
28
|
+
</div>
|
55
29
|
</div>
|
56
30
|
</div>
|
57
|
-
|
58
|
-
<script>
|
59
|
-
$(function() {
|
60
|
-
$('#DataTables_Table_0').DataTable({
|
61
|
-
destroy: true, /* Reinitialize DataTable with config below */
|
62
|
-
'columnDefs': [
|
63
|
-
{ 'orderable': true, 'targets': [0, 1, 2] },
|
64
|
-
{ 'orderable': false, 'targets': [3, 4, 5, 6] }
|
65
|
-
],
|
66
|
-
'language': {
|
67
|
-
'info': 'Showing _START_ to _END_ of _TOTAL_ exporters',
|
68
|
-
'infoEmpty': 'No exporters to show',
|
69
|
-
'infoFiltered': '(filtered from _MAX_ total exporters)',
|
70
|
-
'lengthMenu': 'Show _MENU_ exporters'
|
71
|
-
}
|
72
|
-
})
|
73
|
-
})
|
74
|
-
</script>
|
@@ -14,7 +14,7 @@
|
|
14
14
|
<%= form.button :submit, value: 'Create', class: 'btn btn-primary' %>
|
15
15
|
|
|
16
16
|
<% cancel_path = form.object.persisted? ? exporter_path(form.object) : exporters_path %>
|
17
|
-
<%= link_to t('.cancel'), cancel_path, class: 'btn btn-default ' %>
|
17
|
+
<%= link_to t('bulkrax.cancel'), cancel_path, class: 'btn btn-default ' %>
|
18
18
|
</div>
|
19
19
|
</div>
|
20
20
|
<% end %>
|
@@ -39,8 +39,10 @@
|
|
39
39
|
<strong><%= t('bulkrax.exporter.labels.export_source') %>:</strong>
|
40
40
|
<% case @exporter.export_from %>
|
41
41
|
<% when 'collection' %>
|
42
|
-
|
43
|
-
|
42
|
+
<% collection = Bulkrax.object_factory.find_or_nil(@exporter.export_source) %>
|
43
|
+
<% id = collection&.id || @exporter.export_source %>
|
44
|
+
<% title = collection&.title&.first || @exporter.export_source %>
|
45
|
+
<%= link_to title, hyrax.dashboard_collection_path(id) %>
|
44
46
|
<% when 'importer' %>
|
45
47
|
<% importer = Bulkrax::Importer.find(@exporter.export_source) %>
|
46
48
|
<%= link_to importer.name, bulkrax.importer_path(importer.id) %>
|
@@ -95,16 +97,8 @@
|
|
95
97
|
|
96
98
|
<div class="bulkrax-nav-tab-bottom-margin">
|
97
99
|
<!-- Nav tabs -->
|
98
|
-
<
|
99
|
-
|
100
|
-
<li role="presentation" class="nav-link"><a href="#collection-entries" aria-controls="collection-entries" role="tab" data-toggle="tab"><%= t('bulkrax.exporter.labels.collection_entries') %></a></li>
|
101
|
-
<li role="presentation" class="nav-link"><a href="#file-set-entries" aria-controls="file-set-entries" role="tab" data-toggle="tab"><%= t('bulkrax.exporter.labels.file_set_entries') %></a></li>
|
102
|
-
</ul>
|
103
|
-
<!-- Tab panes -->
|
104
|
-
<div class="tab-content outline">
|
105
|
-
<%= render partial: 'bulkrax/shared/work_entries_tab', locals: { item: @exporter, entries: @work_entries } %>
|
106
|
-
<%= render partial: 'bulkrax/shared/collection_entries_tab', locals: { item: @exporter, entries: @collection_entries } %>
|
107
|
-
<%= render partial: 'bulkrax/shared/file_set_entries_tab', locals: { item: @exporter, entries: @file_set_entries } %>
|
100
|
+
<div class="outline">
|
101
|
+
<%= render partial: 'bulkrax/shared/entries_tab', locals: { item: @exporter } %>
|
108
102
|
</div>
|
109
103
|
<br>
|
110
104
|
<%= link_to 'Edit', edit_exporter_path(@exporter) %>
|
@@ -3,10 +3,10 @@
|
|
3
3
|
f = "#{form.lookup_action}_importer"
|
4
4
|
f = "#{f}_#{@importer.id}" unless @importer.new_record?
|
5
5
|
%>
|
6
|
-
<div id='cloud-files'>
|
6
|
+
<div id='cloud-files'>
|
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
|
-
<span class="
|
9
|
+
<span class="fa fa-plus"></span>
|
10
10
|
Add Cloud Files
|
11
11
|
</button>
|
12
12
|
</div>
|
@@ -25,13 +25,19 @@
|
|
25
25
|
<h4>Add CSV File to Import:</h4>
|
26
26
|
<%# accept a single file upload; data files and bags will need to be added another way %>
|
27
27
|
|
28
|
-
|
28
|
+
<% file_style_list = ['Upload a File', 'Specify a Path on the Server'] %>
|
29
|
+
<% file_style_list << 'Existing Entries' unless importer.new_record? %>
|
30
|
+
<%= fi.input :file_style, collection: file_style_list, as: :radio_buttons, label: false %>
|
29
31
|
<div id='file_upload'>
|
30
|
-
<%= fi.input 'file', as: :file, input_html: { accept: 'text/csv,application/zip' } %><br />
|
32
|
+
<%= fi.input 'file', as: :file, input_html: { accept: 'text/csv,application/zip,application/gzip' } %><br />
|
31
33
|
</div>
|
32
34
|
<div id='file_path'>
|
33
35
|
<%= fi.input :import_file_path, as: :string, input_html: { value: importer.parser_fields['import_file_path'] } %>
|
34
36
|
</div>
|
37
|
+
<div id='existing_options'>
|
38
|
+
<%= fi.collection_check_boxes :entry_statuses, [['Failed'], ['Pending'], ['Skipped'], ['Deleted'], ['Complete']], :first, :first %>
|
39
|
+
</div>
|
40
|
+
|
35
41
|
<% if defined?(::Hyrax) && Hyrax.config.browse_everything? %>
|
36
42
|
<h4>Add Files to Import:</h4>
|
37
43
|
<p>Choose files to upload. The filenames must be unique, and the filenames must be referenced in a column called 'file' in the accompanying CSV file.</p>
|
@@ -34,7 +34,14 @@
|
|
34
34
|
<%= form.button :submit,
|
35
35
|
value: 'Update and Replace Files',
|
36
36
|
class: 'btn btn-primary',
|
37
|
-
|
37
|
+
data: {confirm: "Are you sure? This will remove all files before adding them from the import."} %>
|
38
|
+
<hr />
|
39
|
+
<p>Remove all works and then run the import again from a clean slate. This will remove all files and associations and any edits made since the last import will be lost.</p>
|
40
|
+
<%= form.button :submit,
|
41
|
+
value: 'Remove and Rerun',
|
42
|
+
class: 'btn btn-primary',
|
43
|
+
data: {confirm: "Are you sure? This will delete all the works and any associated files and relationships before re running."} %>
|
44
|
+
|
38
45
|
<% end %>
|
39
46
|
<hr />
|
40
47
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<div class="modal fade" id="bulkraxItemModal" tabindex="-1" role="dialog" aria-labelledby="bulkraxItemModalLabel">
|
2
|
+
<div class="modal-dialog" role="document">
|
3
|
+
<div class="modal-content">
|
4
|
+
<div class="modal-body">
|
5
|
+
<h5>Options for Updating an Entry</h5>
|
6
|
+
<hr />
|
7
|
+
<p>Rebuild metadata and files.</p>
|
8
|
+
<%= link_to 'Build', item_entry_path(item, e), method: :patch, class: 'btn btn-primary' %>
|
9
|
+
<hr />
|
10
|
+
<p>Remove existing work and then recreate the works metadata and files.</p>
|
11
|
+
<%= link_to 'Remove and then Build', item_entry_path(item, e, destroy_first: true), method: :patch, class: 'btn btn-primary' %>
|
12
|
+
</div>
|
13
|
+
<div class="modal-footer">
|
14
|
+
<button type="button" class="btn btn-default" data-dismiss="modal"><%= t('helpers.action.cancel') %></button>
|
15
|
+
</div>
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
</div>
|
@@ -15,7 +15,7 @@
|
|
15
15
|
</button>
|
16
16
|
<%= render 'edit_form_buttons', form: form %>
|
17
17
|
<% cancel_path = form.object.persisted? ? importer_path(form.object) : importers_path %>
|
18
|
-
| <%= link_to t('.cancel'), cancel_path, class: 'btn btn-default ' %>
|
18
|
+
| <%= link_to t('bulkrax.cancel'), cancel_path, class: 'btn btn-default ' %>
|
19
19
|
</div>
|
20
20
|
</div>
|
21
21
|
<% end %>
|
@@ -13,69 +13,25 @@
|
|
13
13
|
|
14
14
|
<div class="panel panel-default">
|
15
15
|
<div class="panel-body">
|
16
|
-
|
17
|
-
<
|
18
|
-
<
|
19
|
-
<
|
20
|
-
<
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
</thead>
|
37
|
-
<tbody>
|
38
|
-
<% @importers.each do |importer| %>
|
39
|
-
<tr>
|
40
|
-
<th scope="row"><%= link_to importer.name, importer_path(importer) %></th>
|
41
|
-
<td><%= importer.status %></td>
|
42
|
-
<td><%= importer.last_imported_at.strftime("%b %d, %Y") if importer.last_imported_at %></td>
|
43
|
-
<td><%= importer.next_import_at.strftime("%b %d, %Y") if importer.next_import_at %></td>
|
44
|
-
<td><%= importer.last_run&.enqueued_records %></td>
|
45
|
-
<td><%= (importer.last_run&.processed_records || 0) %></td>
|
46
|
-
<td><%= (importer.last_run&.failed_records || 0) %></td>
|
47
|
-
<td><%= importer.last_run&.deleted_records %></td>
|
48
|
-
<td><%= importer.last_run&.total_collection_entries %></td>
|
49
|
-
<td><%= importer.last_run&.total_work_entries %></td>
|
50
|
-
<td><%= importer.last_run&.total_file_set_entries %></td>
|
51
|
-
<td><%= link_to raw('<span class="glyphicon glyphicon-info-sign"></span>'), importer_path(importer) %></td>
|
52
|
-
<td><%= link_to raw('<span class="glyphicon glyphicon-pencil"></span>'), edit_importer_path(importer) %></td>
|
53
|
-
<td><%= link_to raw('<span class="glyphicon glyphicon-remove"></span>'), importer, method: :delete, data: { confirm: 'Are you sure?' } %></td>
|
54
|
-
</tr>
|
55
|
-
<% end %>
|
56
|
-
</tbody>
|
57
|
-
</table>
|
58
|
-
</div>
|
59
|
-
<% else %>
|
60
|
-
<p>No importers have been created.</p>
|
61
|
-
<% end %>
|
16
|
+
<div class="table-responsive">
|
17
|
+
<table id='importers-table' class="table table-striped">
|
18
|
+
<thead>
|
19
|
+
<tr>
|
20
|
+
<th scope="col">Name</th>
|
21
|
+
<th scope="col">Status</th>
|
22
|
+
<th scope="col">Last Run</th>
|
23
|
+
<th scope="col">Next Run</th>
|
24
|
+
<th scope="col">Entries Enqueued</th>
|
25
|
+
<th scope="col">Entries Processed</th>
|
26
|
+
<th scope="col">Entries Failed</th>
|
27
|
+
<th scope="col">Entries Deleted Upstream</th>
|
28
|
+
<th scope="col">Total Collection Entries</th>
|
29
|
+
<th scope="col">Total Work Entries</th>
|
30
|
+
<th scope="col">Total File Set Entries</th>
|
31
|
+
<th scope="col">Actions</th>
|
32
|
+
</tr>
|
33
|
+
</thead>
|
34
|
+
</table>
|
35
|
+
</div>
|
62
36
|
</div>
|
63
37
|
</div>
|
64
|
-
|
65
|
-
<script>
|
66
|
-
$(function() {
|
67
|
-
$('#DataTables_Table_0').DataTable({
|
68
|
-
destroy: true, /* Reinitialize DataTable with config below */
|
69
|
-
'columnDefs': [
|
70
|
-
{ 'orderable': true, 'targets': [...Array(10).keys()] },
|
71
|
-
{ 'orderable': false, 'targets': [10, 11, 12] }
|
72
|
-
],
|
73
|
-
'language': {
|
74
|
-
'info': 'Showing _START_ to _END_ of _TOTAL_ importers',
|
75
|
-
'infoEmpty': 'No importers to show',
|
76
|
-
'infoFiltered': '(filtered from _MAX_ total importers)',
|
77
|
-
'lengthMenu': 'Show _MENU_ importers'
|
78
|
-
}
|
79
|
-
})
|
80
|
-
})
|
81
|
-
</script>
|
@@ -18,7 +18,7 @@
|
|
18
18
|
<%= form.button :submit, value: 'Create', class: 'btn btn-primary' %>
|
19
19
|
|
|
20
20
|
<% cancel_path = form.object.persisted? ? importer_path(form.object) : importers_path %>
|
21
|
-
<%= link_to t('.cancel'), cancel_path, class: 'btn btn-default ' %>
|
21
|
+
<%= link_to t('bulkrax.cancel'), cancel_path, class: 'btn btn-default ' %>
|
22
22
|
</div>
|
23
23
|
</div>
|
24
24
|
<% end %>
|
@@ -1,9 +1,10 @@
|
|
1
1
|
<div class="col-xs-12 main-header">
|
2
2
|
<h1><span class="fa fa-cloud-upload" aria-hidden="true"></span> Importer: <%= @importer.name %></h1>
|
3
|
-
|
3
|
+
|
4
|
+
<% if @importer.failed_entries? %>
|
4
5
|
<div class="pull-right">
|
5
|
-
<%= link_to 'Export Errored Entries', importer_export_errors_path(@importer.id), class: 'btn btn-primary' %>
|
6
|
-
<%= link_to 'Upload Corrected Entries', importer_upload_corrected_entries_path(@importer.id), class: 'btn btn-primary' %>
|
6
|
+
<%= link_to 'Export Errored Entries', importer_export_errors_path(@importer.id), class: 'btn btn-primary', data: { turbolinks: false }%>
|
7
|
+
<%= link_to 'Upload Corrected Entries', importer_upload_corrected_entries_path(@importer.id), class: 'btn btn-primary' if @importer.parser.is_a?(Bulkrax::CsvParser) %>
|
7
8
|
</div>
|
8
9
|
<% end %>
|
9
10
|
</div>
|
@@ -44,7 +45,7 @@
|
|
44
45
|
Parser fields:
|
45
46
|
</a>
|
46
47
|
<a role="button" data-toggle="collapse" data-target="#parser-fields-importer-show" aria-expanded="true" aria-controls="parser-fields-importer-show">
|
47
|
-
<div class="accordion-icon
|
48
|
+
<div class="accordion-icon fa fa-times-circle" aria-hidden="true"></div>
|
48
49
|
</a>
|
49
50
|
</div>
|
50
51
|
<div id="parser-fields-importer-show" class="accordion-collapse collapse" role="tabpanel" aria-labelledby="parser-fields-heading">
|
@@ -75,17 +76,10 @@
|
|
75
76
|
|
76
77
|
<div class="bulkrax-nav-tab-bottom-margin">
|
77
78
|
<!-- Nav tabs -->
|
78
|
-
<
|
79
|
-
|
80
|
-
<li role="presentation" class="nav-link"><a href="#collection-entries" aria-controls="collection-entries" role="tab" data-toggle="tab"><%= t('bulkrax.importer.labels.collection_entries') %></a></li>
|
81
|
-
<li role="presentation" class="nav-link"><a href="#file-set-entries" aria-controls="file-set-entries" role="tab" data-toggle="tab"><%= t('bulkrax.importer.labels.file_set_entries') %></a></li>
|
82
|
-
</ul>
|
83
|
-
<!-- Tab panes -->
|
84
|
-
<div class="tab-content outline">
|
85
|
-
<%= render partial: 'bulkrax/shared/work_entries_tab', locals: { item: @importer, entries: @work_entries } %>
|
86
|
-
<%= render partial: 'bulkrax/shared/collection_entries_tab', locals: { item: @importer, entries: @collection_entries } %>
|
87
|
-
<%= render partial: 'bulkrax/shared/file_set_entries_tab', locals: { item: @importer, entries: @file_set_entries } %>
|
79
|
+
<div class="outline">
|
80
|
+
<%= render partial: 'bulkrax/shared/entries_tab', locals: { item: @importer} %>
|
88
81
|
</div>
|
82
|
+
<%= render partial: 'bulkrax/importers/edit_item_buttons', locals: { item: @importer, e: @first_entry } if @first_entry.present? %>
|
89
83
|
</div>
|
90
84
|
|
91
85
|
<p class="bulkrax-p-align">
|
@@ -7,7 +7,7 @@
|
|
7
7
|
<p>
|
8
8
|
Upload <b>only</b> the corrected entries for the <b><%= @importer.name %></b> importer. To export failed entries for correction,
|
9
9
|
<%= link_to importer_export_errors_path(@importer.id) do %>
|
10
|
-
click here <span class='
|
10
|
+
click here <span class='fa fa-download'></span>
|
11
11
|
<% end %>
|
12
12
|
</p>
|
13
13
|
<p>Only CSV files are allowed.</p>
|
@@ -18,7 +18,7 @@
|
|
18
18
|
<div class='fileupload-buttonbar hide-required-tag'>
|
19
19
|
<%= fi.input 'file',
|
20
20
|
as: :file,
|
21
|
-
label: "<span class='
|
21
|
+
label: "<span class='fa fa-plus'></span><span> Add file...</span>".html_safe,
|
22
22
|
label_html: {
|
23
23
|
class: 'btn btn-success'
|
24
24
|
},
|
@@ -5,7 +5,7 @@
|
|
5
5
|
Errors:
|
6
6
|
</a>
|
7
7
|
<a role="button" data-toggle="collapse" data-target="#error-trace-show" aria-expanded="true" aria-controls="error-trace-show">
|
8
|
-
<div class="accordion-icon
|
8
|
+
<div class="accordion-icon fa fa-times-circle" aria-hidden="true"></div>
|
9
9
|
</a>
|
10
10
|
</div>
|
11
11
|
<div id="error-trace-show" class="accordion-collapse collapse" role="tabpanel" aria-labelledby="error-trace-show">
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<strong>Field mapping:</strong>
|
6
6
|
</a>
|
7
7
|
<a role="button" data-toggle="collapse" data-target="#field-mapping-show" aria-expanded="true" aria-controls="field-mapping-show">
|
8
|
-
<div class="accordion-icon
|
8
|
+
<div class="accordion-icon fa fa-times-circle" aria-hidden="true"></div>
|
9
9
|
</a>
|
10
10
|
</div>
|
11
11
|
<div id="field-mapping-show" class="accordion-collapse collapse" role="tabpanel" aria-labelledby="field-mapping-show">
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<div class="tab-pane bulkrax-nav-tab-table-left-align" >
|
2
|
+
<table id='importer-show-table' class='table table-striped'>
|
3
|
+
<thead>
|
4
|
+
<tr>
|
5
|
+
<th><%= t('bulkrax.table_header.labels.identifier') %></th>
|
6
|
+
<th><%= t('bulkrax.table_header.labels.entry_id') %></th>
|
7
|
+
<th><%= t('bulkrax.table_header.labels.status') %></th>
|
8
|
+
<th><%= t('bulkrax.table_header.labels.type') %></th>
|
9
|
+
<th><%= t('bulkrax.table_header.labels.updated_at') %></th>
|
10
|
+
<th><%= t('bulkrax.table_header.labels.errors') %></th>
|
11
|
+
<th><%= t('bulkrax.table_header.labels.actions') %></th>
|
12
|
+
</tr>
|
13
|
+
</thead>
|
14
|
+
</table>
|
15
|
+
<div id='importer-entry-classes' class='hidden'><%= [item.parser.entry_class.to_s, item.parser.collection_entry_class.to_s, item.parser.file_set_entry_class.to_s].compact.join('|') %></div>
|
16
|
+
</div>
|
data/config/routes.rb
CHANGED
@@ -3,15 +3,21 @@
|
|
3
3
|
Bulkrax::Engine.routes.draw do
|
4
4
|
resources :exporters do
|
5
5
|
get :download
|
6
|
-
|
6
|
+
get :entry_table
|
7
|
+
collection do
|
8
|
+
get :exporter_table
|
9
|
+
end
|
10
|
+
resources :entries, only: %i[show update destroy]
|
7
11
|
end
|
8
12
|
resources :importers do
|
9
13
|
put :continue
|
14
|
+
get :entry_table
|
10
15
|
get :export_errors
|
11
16
|
collection do
|
17
|
+
get :importer_table
|
12
18
|
post :external_sets
|
13
19
|
end
|
14
|
-
resources :entries, only: %i[show]
|
20
|
+
resources :entries, only: %i[show update destroy]
|
15
21
|
get :upload_corrected_entries
|
16
22
|
post :upload_corrected_entries_file
|
17
23
|
end
|
@@ -1,14 +1,25 @@
|
|
1
|
+
# This migration comes from bulkrax (originally 20230608153601)
|
1
2
|
class AddIndicesToBulkrax < ActiveRecord::Migration[5.1]
|
2
3
|
def change
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
check_and_add_index :bulkrax_entries, :identifier
|
5
|
+
check_and_add_index :bulkrax_entries, :type
|
6
|
+
check_and_add_index :bulkrax_entries, [:importerexporter_id, :importerexporter_type], name: 'bulkrax_entries_importerexporter_idx'
|
7
|
+
check_and_add_index :bulkrax_pending_relationships, :parent_id
|
8
|
+
check_and_add_index :bulkrax_pending_relationships, :child_id
|
9
|
+
check_and_add_index :bulkrax_statuses, [:statusable_id, :statusable_type], name: 'bulkrax_statuses_statusable_idx'
|
10
|
+
check_and_add_index :bulkrax_statuses, [:runnable_id, :runnable_type], name: 'bulkrax_statuses_runnable_idx'
|
11
|
+
check_and_add_index :bulkrax_statuses, :error_class
|
12
|
+
end
|
9
13
|
|
10
|
-
|
11
|
-
|
12
|
-
|
14
|
+
if RUBY_VERSION =~ /^2/
|
15
|
+
def check_and_add_index(table_name, column_name, options = {})
|
16
|
+
add_index(table_name, column_name, options) unless index_exists?(table_name, column_name, options)
|
17
|
+
end
|
18
|
+
elsif RUBY_VERSION =~ /^3/
|
19
|
+
def check_and_add_index(table_name, column_name, **options)
|
20
|
+
add_index(table_name, column_name, **options) unless index_exists?(table_name, column_name, **options)
|
21
|
+
end
|
22
|
+
else
|
23
|
+
raise "Ruby version #{RUBY_VERSION} is unknown"
|
13
24
|
end
|
14
25
|
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
class DenormalizeStatusMessage < ActiveRecord::Migration[5.2]
|
2
|
+
def change
|
3
|
+
add_column :bulkrax_entries, :status_message, :string, default: 'Pending' unless column_exists?(:bulkrax_entries, :status_message)
|
4
|
+
add_column :bulkrax_importers, :status_message, :string, default: 'Pending' unless column_exists?(:bulkrax_importers, :status_message)
|
5
|
+
add_column :bulkrax_exporters, :status_message, :string, default: 'Pending' unless column_exists?(:bulkrax_exporters, :status_message)
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
class UpdateIdentifierIndex < ActiveRecord::Migration[5.2]
|
2
|
+
def change
|
3
|
+
remove_index :bulkrax_entries, :identifier if index_exists?(:bulkrax_entries, :identifier )
|
4
|
+
add_index :bulkrax_entries, [:identifier, :importerexporter_id, :importerexporter_type], name: 'bulkrax_identifier_idx' unless index_exists?(:bulkrax_entries, [:identifier, :importerexporter_id, :importerexporter_type], name: 'bulkrax_identifier_idx')
|
5
|
+
end
|
6
|
+
end
|