bulkrax 9.3.5 → 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/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 +28 -31
- 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/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/guided_imports/new.html.erb +567 -0
- data/app/views/bulkrax/importers/index.html.erb +6 -1
- data/app/views/bulkrax/importers/new.html.erb +1 -1
- data/app/views/bulkrax/importers/show.html.erb +17 -1
- data/config/i18n-tasks.yml +195 -0
- data/config/locales/bulkrax.de.yml +504 -0
- data/config/locales/bulkrax.en.yml +459 -233
- 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 -1
- data/lib/bulkrax/data/demo_scenarios.json +2235 -0
- data/lib/bulkrax/version.rb +1 -1
- data/lib/bulkrax.rb +31 -0
- metadata +55 -16
- data/app/services/bulkrax/sample_csv_service/column_builder.rb +0 -58
- data/app/services/bulkrax/sample_csv_service/column_descriptor.rb +0 -56
- data/app/services/bulkrax/sample_csv_service/csv_builder.rb +0 -82
- data/app/services/bulkrax/sample_csv_service/explanation_builder.rb +0 -51
- data/app/services/bulkrax/sample_csv_service/field_analyzer.rb +0 -54
- data/app/services/bulkrax/sample_csv_service/file_path_generator.rb +0 -16
- data/app/services/bulkrax/sample_csv_service/mapping_manager.rb +0 -36
- data/app/services/bulkrax/sample_csv_service/model_loader.rb +0 -40
- data/app/services/bulkrax/sample_csv_service/row_builder.rb +0 -33
- data/app/services/bulkrax/sample_csv_service/schema_analyzer.rb +0 -69
- data/app/services/bulkrax/sample_csv_service/split_formatter.rb +0 -42
- data/app/services/bulkrax/sample_csv_service/value_determiner.rb +0 -67
- data/app/services/bulkrax/sample_csv_service.rb +0 -78
- /data/{app/services → lib}/wings/custom_queries/find_by_source_identifier.rb +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 05440b3212ae1571e13cd9ee789c0222b8113a2cf717e4fc84a14f3c2aa2627a
|
|
4
|
+
data.tar.gz: 99d843e51cb362be57e279246fc63937b0772429368142a5a383e7b0a1ccfa4a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7c8d2bd4ec608ceea8b567ebf39972c3e14b300731b8202d133e9a541e29995e69ed6f1dc1528ed5d0c877e38664f05260a60147985da08b65a8c3630cb80ebb
|
|
7
|
+
data.tar.gz: b4a1956d149a23c0bfc299ef3235a36c1d680784283957cb8fe56b06a3745f94d810318a58c9b791a193a76cd218f78129d8e8773b0ff78f8c73bb38d9e6975f
|
data/README.md
CHANGED
|
@@ -195,6 +195,16 @@ Once your the exporter has run, a download icon will appear on the exporters men
|
|
|
195
195
|
* Ruby 2.7 or newer is required
|
|
196
196
|
* Hyrax 2.3 or newer is required
|
|
197
197
|
|
|
198
|
+
## Translations
|
|
199
|
+
|
|
200
|
+
The [i18n-tasks gem](https://github.com/glebm/i18n-tasks) is a static analysis tool that helps manage Rails locale files. It scans the codebase for calls to `t()` and `I18n.t()` and creates a list of all the translation keys then compares that list against what actually exists in the locale files.
|
|
201
|
+
|
|
202
|
+
Useful commands:
|
|
203
|
+
- `bundle exec i18n-tasks` - a list of all tasks
|
|
204
|
+
- `i18n-tasks health` - check for unused keys and files that need formatting
|
|
205
|
+
- `i18n-tasks normalize` - sort and auto-format
|
|
206
|
+
- `i18n-tasks translate-missing` - creates missing translations; **NOTE**: requires a service such as Google Translate
|
|
207
|
+
|
|
198
208
|
## Contributing
|
|
199
209
|
If you're working on a PR for this project, create a feature branch off of `main`.
|
|
200
210
|
|
|
@@ -204,7 +214,7 @@ See
|
|
|
204
214
|
[CONTRIBUTING.md](https://github.com/samvera/bulkrax/blob/main/CONTRIBUTING.md)
|
|
205
215
|
for contributing guidelines.
|
|
206
216
|
|
|
207
|
-
We encourage everyone to help improve this project. Bug reports and pull requests are welcome on GitHub at https://github.com/samvera/bulkrax.
|
|
217
|
+
We encourage everyone to help improve this project. Bug reports and pull requests are welcome on GitHub at https://github.com/samvera/bulkrax. For guided import bugs, use the [Guided import bug report](https://github.com/samvera/bulkrax/issues/new?template=guided_import_bug_report.md) template.
|
|
208
218
|
|
|
209
219
|
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](https://contributor-covenant.org) code of conduct.
|
|
210
220
|
|
|
@@ -10,5 +10,6 @@
|
|
|
10
10
|
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
|
11
11
|
// about supported directives.
|
|
12
12
|
//
|
|
13
|
-
|
|
13
|
+
// IMPORTANT: bulkrax_utils must load first as other files depend on it
|
|
14
|
+
//= require bulkrax/bulkrax_utils
|
|
14
15
|
//= require_tree .
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
// Global JS file for Bulkrax
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
function setupGlobalListeners() {
|
|
4
4
|
// Apply to Importer and Exporter views
|
|
5
5
|
$('button#err_toggle').click(function() {
|
|
6
6
|
$('#error_trace').toggle();
|
|
7
7
|
});
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
$('button#fm_toggle').click(function() {
|
|
10
10
|
$('#field_mapping').toggle();
|
|
11
11
|
});
|
|
12
12
|
|
|
13
|
-
$('#bulkraxItemModal').on('show.bs.modal', function
|
|
13
|
+
$('#bulkraxItemModal').on('show.bs.modal', function(event) {
|
|
14
14
|
var button = $(event.relatedTarget); // Button that triggered the modal
|
|
15
15
|
var recipient = button.data('entry-id'); // Extract info from data-* attributes
|
|
16
16
|
// If necessary, you could initiate an AJAX request here (and then do the updating in a callback).
|
|
@@ -21,4 +21,13 @@ $(document).on('turbolinks:load ready', function() {
|
|
|
21
21
|
});
|
|
22
22
|
return true;
|
|
23
23
|
});
|
|
24
|
-
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Use Turbolinks if available, fallback to Turbo if available, fallback to vanilla JS if needed.
|
|
27
|
+
if (typeof Turbolinks !== 'undefined' && Turbolinks !== null) {
|
|
28
|
+
$(document).on('turbolinks:load ready', setupGlobalListeners);
|
|
29
|
+
} else if (typeof Turbo !== 'undefined') {
|
|
30
|
+
$(document).on('turbo:load ready', setupGlobalListeners);
|
|
31
|
+
} else {
|
|
32
|
+
$(document).on('ready', setupGlobalListeners);
|
|
33
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// Bulkrax Utilities - Reusable helper functions
|
|
2
|
+
// Used across Bulkrax JavaScript modules
|
|
3
|
+
|
|
4
|
+
; (function () {
|
|
5
|
+
'use strict'
|
|
6
|
+
|
|
7
|
+
// Create namespace
|
|
8
|
+
window.BulkraxUtils = window.BulkraxUtils || {}
|
|
9
|
+
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// HTML & STRING UTILITIES
|
|
12
|
+
// ============================================================================
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Escape HTML to prevent XSS attacks
|
|
16
|
+
* @param {string} unsafe - Untrusted user input
|
|
17
|
+
* @returns {string} HTML-safe string
|
|
18
|
+
*/
|
|
19
|
+
function escapeHtml(unsafe) {
|
|
20
|
+
if (!unsafe) return ''
|
|
21
|
+
return unsafe
|
|
22
|
+
.toString()
|
|
23
|
+
.replace(/&/g, '&')
|
|
24
|
+
.replace(/</g, '<')
|
|
25
|
+
.replace(/>/g, '>')
|
|
26
|
+
.replace(/"/g, '"')
|
|
27
|
+
.replace(/'/g, ''')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// FILE UTILITIES
|
|
32
|
+
// ============================================================================
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Format file size in human-readable format
|
|
36
|
+
* @param {number} bytes - File size in bytes
|
|
37
|
+
* @returns {string} Formatted size (e.g., "1.5 MB")
|
|
38
|
+
*/
|
|
39
|
+
function formatFileSize(bytes) {
|
|
40
|
+
if (bytes === 0) return '0 Bytes'
|
|
41
|
+
var k = 1024
|
|
42
|
+
var sizes = ['Bytes', 'KB', 'MB', 'GB']
|
|
43
|
+
var i = Math.floor(Math.log(bytes) / Math.log(k))
|
|
44
|
+
return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i]
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ============================================================================
|
|
48
|
+
// DATA NORMALIZATION
|
|
49
|
+
// ============================================================================
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Normalize boolean or string boolean to actual boolean
|
|
53
|
+
* Handles both boolean types and string representations
|
|
54
|
+
* @param {boolean|string} value - Value to normalize
|
|
55
|
+
* @returns {boolean|null} true, false, or null if indeterminate
|
|
56
|
+
*/
|
|
57
|
+
function normalizeBoolean(value) {
|
|
58
|
+
if (value === true || value === 'true') return true
|
|
59
|
+
if (value === false || value === 'false') return false
|
|
60
|
+
return null
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ============================================================================
|
|
64
|
+
// INTERNATIONALIZATION
|
|
65
|
+
// ============================================================================
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Look up a translation key from BulkraxI18n and interpolate variables.
|
|
69
|
+
* Falls back to the key name if not found.
|
|
70
|
+
* @param {string} key - Translation key (e.g. 'file_upload_error')
|
|
71
|
+
* @param {Object} [vars] - Interpolation variables (e.g. {count: 5})
|
|
72
|
+
* @returns {string} Translated and interpolated string
|
|
73
|
+
*/
|
|
74
|
+
function t(key, vars) {
|
|
75
|
+
var translations = window.BulkraxI18n || {}
|
|
76
|
+
var text = translations[key]
|
|
77
|
+
if (text == null) return key
|
|
78
|
+
if (vars) {
|
|
79
|
+
Object.keys(vars).forEach(function (k) {
|
|
80
|
+
text = text.replace(new RegExp('%\\{' + k + '\\}', 'g'), vars[k])
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
return text
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ============================================================================
|
|
87
|
+
// PUBLIC API
|
|
88
|
+
// ============================================================================
|
|
89
|
+
|
|
90
|
+
window.BulkraxUtils = {
|
|
91
|
+
escapeHtml: escapeHtml,
|
|
92
|
+
formatFileSize: formatFileSize,
|
|
93
|
+
normalizeBoolean: normalizeBoolean,
|
|
94
|
+
t: t
|
|
95
|
+
}
|
|
96
|
+
})()
|
|
@@ -45,6 +45,7 @@ Blacklight.onLoad(function() {
|
|
|
45
45
|
"ajax": window.location.href.replace(/(\/importers)/, "$1/importer_table.json"),
|
|
46
46
|
"pageLength": 30,
|
|
47
47
|
"lengthMenu": [[30, 100, 200], [30, 100, 200]],
|
|
48
|
+
"order": [[2, 'desc']],
|
|
48
49
|
"columns": [
|
|
49
50
|
{ "data": "name" },
|
|
50
51
|
{ "data": "status_message" },
|
|
@@ -1,15 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
$( "#error_trace" ).toggle();
|
|
1
|
+
function setupButtonToggles() {
|
|
2
|
+
$("button#entry_error").click(function() {
|
|
3
|
+
$("#error_trace").toggle();
|
|
5
4
|
});
|
|
6
5
|
|
|
7
|
-
$(
|
|
8
|
-
$(
|
|
6
|
+
$("button#raw_button").click(function() {
|
|
7
|
+
$("#raw_metadata").toggle();
|
|
9
8
|
});
|
|
10
9
|
|
|
11
|
-
$(
|
|
12
|
-
$(
|
|
10
|
+
$("button#parsed_button").click(function() {
|
|
11
|
+
$("#parsed_metadata").toggle();
|
|
13
12
|
});
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Use Turbolinks if available, fallback to Turbo if available, fallback to vanilla JS if needed.
|
|
16
|
+
if (typeof Turbolinks !== 'undefined' && Turbolinks !== null) {
|
|
17
|
+
$(document).on('turbolinks:load ready', setupButtonToggles());
|
|
18
|
+
} else if (typeof Turbo !== 'undefined') {
|
|
19
|
+
$(document).on('turbo:load ready', setupButtonToggles());
|
|
20
|
+
} else {
|
|
21
|
+
$(document).on('DOMContentLoaded', setupButtonToggles());
|
|
22
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
function prepBulkrax(event) {
|
|
5
5
|
if($('form#new_importer, form.edit_importer').length < 1) {
|
|
6
|
-
return
|
|
6
|
+
return;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
var refresh_button = $('.refresh-set-source');
|
|
@@ -247,4 +247,11 @@ function setError(selector, error) {
|
|
|
247
247
|
selector.attr('disabled', true);
|
|
248
248
|
}
|
|
249
249
|
|
|
250
|
-
|
|
250
|
+
// Use Turbolinks if available, fallback to Turbo if available, fallback to jQuery if needed.
|
|
251
|
+
if (typeof Turbolinks !== 'undefined' && Turbolinks !== null) {
|
|
252
|
+
$(document).on('turbolinks:load', prepBulkrax);
|
|
253
|
+
} else if (typeof Turbo !== 'undefined') {
|
|
254
|
+
$(document).on('turbo:load', prepBulkrax);
|
|
255
|
+
} else {
|
|
256
|
+
$(document).ready(prepBulkrax);
|
|
257
|
+
}
|