bulkrax 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +205 -0
  3. data/README.md +202 -0
  4. data/Rakefile +42 -0
  5. data/app/assets/config/bulkrax_manifest.js +2 -0
  6. data/app/assets/javascripts/bulkrax/application.js +14 -0
  7. data/app/assets/javascripts/bulkrax/bulkrax.js +11 -0
  8. data/app/assets/javascripts/bulkrax/entries.js +15 -0
  9. data/app/assets/javascripts/bulkrax/exporters.js +60 -0
  10. data/app/assets/javascripts/bulkrax/importers.js.erb +166 -0
  11. data/app/assets/stylesheets/bulkrax/accordion.scss +40 -0
  12. data/app/assets/stylesheets/bulkrax/application.css +15 -0
  13. data/app/assets/stylesheets/bulkrax/coderay.scss +264 -0
  14. data/app/assets/stylesheets/bulkrax/import_export.scss +37 -0
  15. data/app/controllers/bulkrax/application_controller.rb +8 -0
  16. data/app/controllers/bulkrax/entries_controller.rb +44 -0
  17. data/app/controllers/bulkrax/exporters_controller.rb +125 -0
  18. data/app/controllers/bulkrax/importers_controller.rb +315 -0
  19. data/app/controllers/concerns/bulkrax/api.rb +29 -0
  20. data/app/factories/bulkrax/object_factory.rb +230 -0
  21. data/app/helpers/bulkrax/application_helper.rb +15 -0
  22. data/app/helpers/bulkrax/exporters_helper.rb +6 -0
  23. data/app/helpers/bulkrax/importers_helper.rb +13 -0
  24. data/app/helpers/bulkrax/validation_helper.rb +153 -0
  25. data/app/jobs/bulkrax/application_job.rb +6 -0
  26. data/app/jobs/bulkrax/child_relationships_job.rb +128 -0
  27. data/app/jobs/bulkrax/delete_work_job.rb +16 -0
  28. data/app/jobs/bulkrax/download_cloud_file_job.rb +18 -0
  29. data/app/jobs/bulkrax/export_work_job.rb +37 -0
  30. data/app/jobs/bulkrax/exporter_job.rb +14 -0
  31. data/app/jobs/bulkrax/import_work_collection_job.rb +41 -0
  32. data/app/jobs/bulkrax/import_work_job.rb +32 -0
  33. data/app/jobs/bulkrax/importer_job.rb +26 -0
  34. data/app/mailers/bulkrax/application_mailer.rb +8 -0
  35. data/app/matchers/bulkrax/application_matcher.rb +113 -0
  36. data/app/matchers/bulkrax/bagit_matcher.rb +6 -0
  37. data/app/matchers/bulkrax/csv_matcher.rb +6 -0
  38. data/app/matchers/bulkrax/oai_matcher.rb +6 -0
  39. data/app/models/bulkrax/application_record.rb +7 -0
  40. data/app/models/bulkrax/csv_collection_entry.rb +19 -0
  41. data/app/models/bulkrax/csv_entry.rb +163 -0
  42. data/app/models/bulkrax/entry.rb +104 -0
  43. data/app/models/bulkrax/exporter.rb +122 -0
  44. data/app/models/bulkrax/exporter_run.rb +7 -0
  45. data/app/models/bulkrax/import_failed.rb +13 -0
  46. data/app/models/bulkrax/importer.rb +155 -0
  47. data/app/models/bulkrax/importer_run.rb +8 -0
  48. data/app/models/bulkrax/oai_dc_entry.rb +6 -0
  49. data/app/models/bulkrax/oai_entry.rb +74 -0
  50. data/app/models/bulkrax/oai_qualified_dc_entry.rb +6 -0
  51. data/app/models/bulkrax/oai_set_entry.rb +19 -0
  52. data/app/models/bulkrax/rdf_collection_entry.rb +19 -0
  53. data/app/models/bulkrax/rdf_entry.rb +90 -0
  54. data/app/models/bulkrax/status.rb +25 -0
  55. data/app/models/bulkrax/xml_entry.rb +73 -0
  56. data/app/models/concerns/bulkrax/download_behavior.rb +61 -0
  57. data/app/models/concerns/bulkrax/errored_entries.rb +45 -0
  58. data/app/models/concerns/bulkrax/export_behavior.rb +58 -0
  59. data/app/models/concerns/bulkrax/file_factory.rb +140 -0
  60. data/app/models/concerns/bulkrax/has_local_processing.rb +7 -0
  61. data/app/models/concerns/bulkrax/has_matchers.rb +155 -0
  62. data/app/models/concerns/bulkrax/import_behavior.rb +90 -0
  63. data/app/models/concerns/bulkrax/importer_exporter_behavior.rb +34 -0
  64. data/app/models/concerns/bulkrax/status_info.rb +56 -0
  65. data/app/parsers/bulkrax/application_parser.rb +299 -0
  66. data/app/parsers/bulkrax/bagit_parser.rb +157 -0
  67. data/app/parsers/bulkrax/csv_parser.rb +266 -0
  68. data/app/parsers/bulkrax/oai_dc_parser.rb +130 -0
  69. data/app/parsers/bulkrax/oai_qualified_dc_parser.rb +9 -0
  70. data/app/parsers/bulkrax/xml_parser.rb +103 -0
  71. data/app/views/bulkrax/entries/_parsed_metadata.html.erb +19 -0
  72. data/app/views/bulkrax/entries/_raw_metadata.html.erb +19 -0
  73. data/app/views/bulkrax/entries/show.html.erb +63 -0
  74. data/app/views/bulkrax/exporters/_form.html.erb +120 -0
  75. data/app/views/bulkrax/exporters/edit.html.erb +23 -0
  76. data/app/views/bulkrax/exporters/index.html.erb +67 -0
  77. data/app/views/bulkrax/exporters/new.html.erb +23 -0
  78. data/app/views/bulkrax/exporters/show.html.erb +124 -0
  79. data/app/views/bulkrax/importers/_bagit_fields.html.erb +54 -0
  80. data/app/views/bulkrax/importers/_browse_everything.html.erb +12 -0
  81. data/app/views/bulkrax/importers/_csv_fields.html.erb +39 -0
  82. data/app/views/bulkrax/importers/_edit_form_buttons.html.erb +16 -0
  83. data/app/views/bulkrax/importers/_form.html.erb +35 -0
  84. data/app/views/bulkrax/importers/_oai_fields.html.erb +42 -0
  85. data/app/views/bulkrax/importers/_xml_fields.html.erb +60 -0
  86. data/app/views/bulkrax/importers/edit.html.erb +20 -0
  87. data/app/views/bulkrax/importers/index.html.erb +77 -0
  88. data/app/views/bulkrax/importers/new.html.erb +25 -0
  89. data/app/views/bulkrax/importers/show.html.erb +175 -0
  90. data/app/views/bulkrax/importers/upload_corrected_entries.html.erb +37 -0
  91. data/app/views/bulkrax/shared/_bulkrax_errors.html.erb +52 -0
  92. data/app/views/bulkrax/shared/_bulkrax_field_mapping.html.erb +39 -0
  93. data/app/views/hyrax/dashboard/sidebar/_bulkrax_sidebar_additions.html.erb +6 -0
  94. data/app/views/hyrax/dashboard/sidebar/_repository_content.html.erb +19 -0
  95. data/app/views/layouts/bulkrax/application.html.erb +14 -0
  96. data/config/locales/bulkrax.en.yml +36 -0
  97. data/config/routes.rb +18 -0
  98. data/db/migrate/20181011230201_create_bulkrax_importers.rb +18 -0
  99. data/db/migrate/20181011230228_create_bulkrax_importer_runs.rb +16 -0
  100. data/db/migrate/20190325183136_create_bulkrax_entries.rb +16 -0
  101. data/db/migrate/20190601221109_add_status_to_entry.rb +9 -0
  102. data/db/migrate/20190715161939_add_collections_to_importer_runs.rb +6 -0
  103. data/db/migrate/20190715162044_change_collection_ids_on_entries.rb +5 -0
  104. data/db/migrate/20190729124607_create_bulkrax_exporters.rb +19 -0
  105. data/db/migrate/20190729134158_create_bulkrax_exporter_runs.rb +14 -0
  106. data/db/migrate/20190731114016_change_importer_and_exporter_to_polymorphic.rb +12 -0
  107. data/db/migrate/20191203225129_add_total_collection_records_to_importer_runs.rb +5 -0
  108. data/db/migrate/20191204191623_add_children_to_importer_runs.rb +6 -0
  109. data/db/migrate/20191204223857_change_total_records_to_total_work_entries.rb +6 -0
  110. data/db/migrate/20191212155530_change_entry_last_error.rb +19 -0
  111. data/db/migrate/20200108194557_add_validate_only_to_bulkrax_importers.rb +5 -0
  112. data/db/migrate/20200301232856_add_status_to_importers.rb +9 -0
  113. data/db/migrate/20200312190638_remove_foreign_key_from_bulkrax_entries.rb +5 -0
  114. data/db/migrate/20200326235838_add_status_to_exporters.rb +7 -0
  115. data/db/migrate/20200601204556_add_invalid_record_to_importer_run.rb +5 -0
  116. data/db/migrate/20200818055819_create_bulkrax_statuses.rb +18 -0
  117. data/db/migrate/20200819054016_move_to_statuses.rb +30 -0
  118. data/db/migrate/20201106014204_add_date_filter_and_status_to_bulkrax_exporters.rb +7 -0
  119. data/db/migrate/20201117220007_add_workflow_status_to_bulkrax_exporter.rb +5 -0
  120. data/db/migrate/20210806044408_remove_unused_last_error.rb +7 -0
  121. data/db/migrate/20210806065737_increase_text_sizes.rb +12 -0
  122. data/lib/bulkrax.rb +161 -0
  123. data/lib/bulkrax/engine.rb +37 -0
  124. data/lib/bulkrax/version.rb +5 -0
  125. data/lib/generators/bulkrax/install_generator.rb +80 -0
  126. data/lib/generators/bulkrax/templates/README +3 -0
  127. data/lib/generators/bulkrax/templates/app/assets/images/bulkrax/removed.png +0 -0
  128. data/lib/generators/bulkrax/templates/app/models/concerns/bulkrax/has_local_processing.rb +8 -0
  129. data/lib/generators/bulkrax/templates/bin/importer +140 -0
  130. data/lib/generators/bulkrax/templates/config/bulkrax_api.yml +84 -0
  131. data/lib/generators/bulkrax/templates/config/initializers/bulkrax.rb +72 -0
  132. data/lib/tasks/bulkrax_tasks.rake +6 -0
  133. metadata +388 -0
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bulkrax
4
+ class OaiQualifiedDcParser < OaiDcParser
5
+ def entry_class
6
+ OaiQualifiedDcEntry
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bulkrax
4
+ class XmlParser < ApplicationParser
5
+ def entry_class
6
+ Bulkrax::XmlEntry
7
+ end
8
+
9
+ # @todo not yet supported
10
+ def collection_entry_class; end
11
+
12
+ # @todo not yet supported
13
+ def create_collections; end
14
+
15
+ # @todo not yet supported
16
+ def import_fields; end
17
+
18
+ def valid_import?
19
+ raise StandardError, 'No metadata files found' if metadata_paths.blank?
20
+ raise StandardError, 'No records found' if records.blank?
21
+ true
22
+ rescue StandardError => e
23
+ status_info(e)
24
+ false
25
+ end
26
+
27
+ # For multiple, we expect to find metadata for multiple works in the given metadata file(s)
28
+ # For single, we expect to find metadata for a single work in the given metadata file(s)
29
+ # if the file contains more than one record, we take only the first
30
+ # In either case there may be multiple metadata files returned by metadata_paths
31
+ def records(_opts = {})
32
+ @records ||=
33
+ if parser_fields['import_type'] == 'multiple'
34
+ r = []
35
+ metadata_paths.map do |md|
36
+ # Retrieve all records
37
+ elements = entry_class.read_data(md).xpath("//#{record_element}")
38
+ r += elements.map { |el| entry_class.data_for_entry(el, source_identifier) }
39
+ end
40
+ # Flatten because we may have multiple records per array
41
+ r.compact.flatten
42
+ elsif parser_fields['import_type'] == 'single'
43
+ metadata_paths.map do |md|
44
+ data = entry_class.read_data(md).xpath("//#{record_element}").first # Take only the first record
45
+ entry_class.data_for_entry(data, source_identifier)
46
+ end.compact # No need to flatten because we take only the first record
47
+ end
48
+ end
49
+
50
+ def record_element
51
+ parser_fields['record_element']
52
+ end
53
+
54
+ # Return all files in the import directory and sub-directories
55
+ def file_paths
56
+ @file_paths ||=
57
+ # Relative to the file
58
+ if file?
59
+ Dir.glob("#{File.dirname(import_file_path)}/**/*").reject { |f| File.file?(f) == false }
60
+ # In the supplied directory
61
+ else
62
+ Dir.glob("#{import_file_path}/**/*").reject { |f| File.file?(f) == false }
63
+ end
64
+ end
65
+
66
+ # If the import_file_path is an xml file, return that
67
+ # Otherwise return all xml files in the given folder
68
+ def metadata_paths
69
+ @metadata_paths ||=
70
+ if file? && MIME::Types.type_for(import_file_path).include?('application/xml')
71
+ [import_file_path]
72
+ else
73
+ file_paths.select do |f|
74
+ MIME::Types.type_for(f).include?('application/xml') &&
75
+ f.include?("import_#{importerexporter.id}")
76
+ end
77
+ end
78
+ end
79
+
80
+ def create_works
81
+ records.each_with_index do |record, index|
82
+ next unless record_has_source_identifier(record, index)
83
+ break if !limit.nil? && index >= limit
84
+
85
+ seen[record[source_identifier]] = true
86
+ new_entry = find_or_create_entry(entry_class, record[source_identifier], 'Bulkrax::Importer', record)
87
+ if record[:delete].present?
88
+ DeleteWorkJob.send(perform_method, new_entry, current_run)
89
+ else
90
+ ImportWorkJob.send(perform_method, new_entry.id, current_run.id)
91
+ end
92
+ increment_counters(index)
93
+ end
94
+ importer.record_status
95
+ rescue StandardError => e
96
+ status_info(e)
97
+ end
98
+
99
+ def total
100
+ records.size
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,19 @@
1
+ <% if @entry.parsed_metadata.present? %>
2
+ <div class="accordion-container">
3
+ <div class="accordion-heading" role="tab" id="parsed-metadata-heading">
4
+ <a class="accordion-title" role="button" data-toggle="collapse" data-target="#parsed-metadata-show" aria-expanded="true" aria-controls="parsed-metadata-show">
5
+ Parsed Metadata:
6
+ </a>
7
+ <a role="button" data-toggle="collapse" data-target="#parsed-metadata-show" aria-expanded="true" aria-controls="parsed-metadata-show">
8
+ <div class="accordion-icon glyphicon glyphicon-remove-circle" aria-hidden="true"></div>
9
+ </a>
10
+ </div>
11
+ <div id="parsed-metadata-show" class="accordion-collapse collapse" role="tabpanel" aria-labelledby="parsed-metadata-show">
12
+ <div class="accordion-body">
13
+ <% @entry.parsed_metadata.each do |k, v| %>
14
+ <strong><%= k %>:</strong> <%= v %><br>
15
+ <% end %>
16
+ </div>
17
+ </div>
18
+ </div>
19
+ <% end %>
@@ -0,0 +1,19 @@
1
+ <% if @entry.raw_metadata.present? %>
2
+ <div class="accordion-container">
3
+ <div class="accordion-heading" role="tab" id="raw-metadata-heading">
4
+ <a class="accordion-title" role="button" data-toggle="collapse" data-target="#raw-metadata-show" aria-expanded="true" aria-controls="raw-metadata-show">
5
+ Raw Metadata:
6
+ </a>
7
+ <a role="button" data-toggle="collapse" data-target="#raw-metadata-show" aria-expanded="true" aria-controls="raw-metadata-show">
8
+ <div class="accordion-icon glyphicon glyphicon-remove-circle" aria-hidden="true"></div>
9
+ </a>
10
+ </div>
11
+ <div id="raw-metadata-show" class="accordion-collapse collapse" role="tabpanel" aria-labelledby="raw-metadata-show">
12
+ <div class="accordion-body">
13
+ <% @entry.raw_metadata.each do |k, v| %>
14
+ <strong><%= k %>:</strong> <%= v %><br>
15
+ <% end %>
16
+ </div>
17
+ </div>
18
+ </div>
19
+ <% end %>
@@ -0,0 +1,63 @@
1
+ <p id="notice"><%= notice %></p>
2
+ <div class="panel panel-default">
3
+ <div class="panel-body">
4
+ <p class='bulkrax-p-align'>
5
+ <strong>Identifier:</strong>
6
+ <%= @entry.identifier %>
7
+ </p>
8
+
9
+ <p class='bulkrax-p-align'>
10
+ <strong>Entry ID:</strong>
11
+ <%= @entry.id %>
12
+ </p>
13
+
14
+ <p class='bulkrax-p-align'>
15
+ <strong>Type:</strong>
16
+ <%= @entry.factory_class || 'Unknown' %>
17
+ </p>
18
+ <%= render partial: 'raw_metadata'%>
19
+
20
+ <%= render partial: 'parsed_metadata'%>
21
+
22
+ <%= render partial: 'bulkrax/shared/bulkrax_errors', locals: {item: @entry} %>
23
+
24
+ <p class="bulkrax-p-align">
25
+ <% if @importer.present? %>
26
+ <strong>Importer:</strong>
27
+ <%= link_to @importer.name, importer_path(@importer) %>
28
+ <% elsif @exporter.present? %>
29
+ <strong>Exporter:</strong>
30
+ <%= link_to @exporter.name, exporter_path(@exporter) %>
31
+ <% end %>
32
+ </p>
33
+
34
+ <p class='bulkrax-p-align'>
35
+ <% if @importer.present? %>
36
+ <% factory_record = @entry.factory.find %>
37
+ <% if factory_record.present? && @entry.factory_class %>
38
+ <strong><%= @entry.factory_class.to_s %> Link:</strong>
39
+ <% if @entry.factory_class.to_s == 'Collection' %>
40
+ <%= link_to @entry.factory_class.to_s, hyrax.polymorphic_path(factory_record) %>
41
+ <% else %>
42
+ <%= link_to @entry.factory_class.to_s, main_app.polymorphic_path(factory_record) %>
43
+ <% end %>
44
+ <% else %>
45
+ <strong>Item Link:</strong> Item has not yet been imported successfully
46
+ <% end %>
47
+ <% else %>
48
+ <% record = @entry&.hyrax_record %>
49
+ <% if record.present? && @entry.factory_class %>
50
+ <strong><%= record.class.to_s %> Link:</strong>
51
+ <% if record.is_a?(Collection) %>
52
+ <%= link_to record.class.to_s, hyrax.polymorphic_path(record) %>
53
+ <% else %>
54
+ <%= link_to record.class.to_s, main_app.polymorphic_path(record) %>
55
+ <% end %>
56
+ <% else %>
57
+ <strong>Item Link:</strong> No item associated with this entry or class unknown
58
+ <% end %>
59
+ <% end %>
60
+ </p>
61
+
62
+ </div>
63
+ </div>
@@ -0,0 +1,120 @@
1
+ <div class="panel-body">
2
+ <% if exporter.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(exporter.errors.count, "error") %> prohibited this exporter from being saved:</h2>
5
+
6
+ <ul>
7
+ <% exporter.errors.full_messages.each do |message| %>
8
+ <li><%= message %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <%= form.input :name, label: t('bulkrax.exporter.labels.name') %>
15
+
16
+ <%= form.hidden_field :user_id, value: current_user.id %>
17
+
18
+ <%= form.input :export_type,
19
+ collection: form.object.export_type_list,
20
+ label: t('bulkrax.exporter.labels.export_type'),
21
+ required: true,
22
+ prompt: 'Please select an export type' %>
23
+
24
+ <%= form.input :export_from,
25
+ collection: form.object.export_from_list,
26
+ label: t('bulkrax.exporter.labels.export_from'),
27
+ required: true,
28
+ prompt: 'Please select an export source' %>
29
+
30
+ <%= form.input :export_source_importer,
31
+ label: t('bulkrax.exporter.labels.importer'),
32
+ prompt: 'Select from the list',
33
+ label_html: { class: 'importer export-source-option hidden' },
34
+ input_html: { class: 'importer export-source-option hidden' },
35
+ collection: form.object.importers_list %>
36
+
37
+ <%= form.input :export_source_collection,
38
+ prompt: 'Start typing ...',
39
+ label: t('bulkrax.exporter.labels.collection'),
40
+ placeholder: @collection&.title&.first,
41
+ label_html: { class: 'collection export-source-option hidden' },
42
+ input_html: {
43
+ class: 'collection export-source-option hidden',
44
+ data: {
45
+ 'autocomplete-url' => '/authorities/search/collections',
46
+ 'autocomplete' => 'collection'
47
+ }
48
+ }
49
+ %>
50
+
51
+ <%= form.input :export_source_worktype,
52
+ label: t('bulkrax.exporter.labels.worktype'),
53
+ prompt: 'Select from the list',
54
+ label_html: { class: 'worktype export-source-option hidden' },
55
+ input_html: { class: 'worktype export-source-option hidden' },
56
+ collection: Hyrax.config.curation_concerns.map {|cc| [cc.to_s, cc.to_s] } %>
57
+
58
+ <%= form.input :limit,
59
+ as: :integer,
60
+ hint: 'leave blank or 0 for all records',
61
+ label: t('bulkrax.exporter.labels.limit') %>
62
+
63
+ <%= form.input :date_filter,
64
+ as: :boolean,
65
+ label: t('bulkrax.exporter.labels.filter_by_date') %>
66
+ <div id="date_filter_picker" class="hidden">
67
+ <%= form.input :start_date,
68
+ as: :date,
69
+ label: t('bulkrax.exporter.labels.start_date') %>
70
+
71
+ <%= form.input :finish_date,
72
+ as: :date,
73
+ label: t('bulkrax.exporter.labels.finish_date') %>
74
+ </div>
75
+ <%= form.input :work_visibility,
76
+ collection: form.object.work_visibility_list,
77
+ label: t('bulkrax.exporter.labels.visibility') %>
78
+
79
+ <%= form.input :workflow_status,
80
+ collection: form.object.workflow_status_list,
81
+ label: t('bulkrax.exporter.labels.status') %>
82
+
83
+ <%= form.input :parser_klass,
84
+ collection: Bulkrax.parsers.map {|p| [p[:name], p[:class_name], {'data-partial' => p[:partial]}] if p[:class_name].constantize.export_supported? }.compact,
85
+ label: t('bulkrax.exporter.labels.export_format') %>
86
+ </div>
87
+
88
+ <%# Find definitions for the functions called in this script in
89
+ app/assets/javascripts/bulkrax/exporters.js %>
90
+ <script>
91
+ $(function() {
92
+ // show the selected export_source option
93
+ var selectedVal = $('.exporter_export_from option:selected').val();
94
+ hideUnhide(selectedVal);
95
+
96
+ // Select2 dropdowns don't like taking a value param. Thus,
97
+ // if export_source_collection is present, we populate the input.
98
+ var selectedCollectionId = "<%= @collection&.id %>"
99
+ if (selectedCollectionId.length > 0) {
100
+ $('#exporter_export_source_collection').val(selectedCollectionId)
101
+ }
102
+
103
+ // get the selected export_from option and show the corresponding export_source
104
+ $('.exporter_export_from').change(function() {
105
+ var selectedVal = $('.exporter_export_from option:selected').val();
106
+ hideUnhide(selectedVal);
107
+ });
108
+
109
+ // get the date filter option and show the corresponding date selectors
110
+ $('.exporter_date_filter').change(function() {
111
+ if($('.exporter_date_filter').find(".boolean").is(":checked"))
112
+ $('#date_filter_picker').removeClass('hidden');
113
+ else
114
+ $('#date_filter_picker').addClass('hidden');
115
+ });
116
+
117
+ if($('.exporter_date_filter').find(".boolean").is(":checked"))
118
+ $('#date_filter_picker').removeClass('hidden');
119
+ });
120
+ </script>
@@ -0,0 +1,23 @@
1
+ <% provide :page_header do %>
2
+ <h1><span class="fa fa-edit" aria-hidden="true"></span> Edit Exporter</h1>
3
+ <% end %>
4
+
5
+ <div class="row">
6
+ <div class="col-md-12">
7
+ <div class="panel panel-default tabs">
8
+ <%= simple_form_for @exporter do |form| %>
9
+ <%= render 'form', exporter: @exporter, form: form %>
10
+ <div class="panel-footer">
11
+ <div class='pull-right'>
12
+ <%= form.button :submit, value: 'Update Exporter', class: 'btn btn-primary' %>
13
+ |
14
+ <%= form.button :submit, value: 'Update and Re-Export All Items', class: 'btn btn-primary' %>
15
+ |
16
+ <% cancel_path = form.object.persisted? ? exporter_path(form.object) : exporters_path %>
17
+ <%= link_to t('.cancel'), cancel_path, class: 'btn btn-default ' %>
18
+ </div>
19
+ </div>
20
+ <% end %>
21
+ </div>
22
+ </div>
23
+ </div>
@@ -0,0 +1,67 @@
1
+ <% provide :page_header do %>
2
+ <h1><span class="fa fa-cloud-download" aria-hidden="true"></span> Exporters</h1>
3
+ <div class="pull-right">
4
+ <%= link_to new_exporter_path, class: 'btn btn-primary' do %>
5
+ <span class="fa fa-edit" aria-hidden="true"></span> <%= t(:'helpers.action.exporter.new') %>
6
+ <% end %>
7
+ </div>
8
+ <% end %>
9
+
10
+ <div class="panel panel-default">
11
+ <div class="panel-body">
12
+ <% if @exporters.present? %>
13
+ <div class="table-responsive">
14
+ <table class="table table-striped datatable">
15
+ <thead>
16
+ <tr>
17
+ <th scope="col">Name</th>
18
+ <th scope="col">Status</th>
19
+ <th scope="col">Date Exported</th>
20
+ <th scope="col"></th>
21
+ <th scope="col"></th>
22
+ <th scope="col"></th>
23
+ <th scope="col"></th>
24
+ </tr>
25
+ </thead>
26
+ <tbody>
27
+ <% @exporters.each do |exporter| %>
28
+ <tr>
29
+ <th scope="row"><%= link_to exporter.name, exporter_path(exporter) %></th>
30
+ <td><%= exporter.status %></td>
31
+ <td><%= exporter.created_at %></td>
32
+ <td>
33
+ <% if File.exist?(exporter.exporter_export_zip_path) %>
34
+ <%= link_to raw('<span class="glyphicon glyphicon-download"></span>'), exporter_download_path(exporter) %>
35
+ <% end%>
36
+ </td>
37
+ <td><%= link_to raw('<span class="glyphicon glyphicon-info-sign"></span>'), exporter_path(exporter) %></td>
38
+ <td><%= link_to raw('<span class="glyphicon glyphicon-pencil"></span>'), edit_exporter_path(exporter) %></td>
39
+ <td><%= link_to raw('<span class="glyphicon glyphicon-remove"></span>'), exporter, method: :delete, data: { confirm: 'Are you sure?' } %></td>
40
+ </tr>
41
+ <% end %>
42
+ </tbody>
43
+ </table>
44
+ </div>
45
+ <% else %>
46
+ <p>No exporters have been created.</p>
47
+ <% end %>
48
+ </div>
49
+ </div>
50
+
51
+ <script>
52
+ $(function() {
53
+ $('#DataTables_Table_0').DataTable({
54
+ destroy: true, /* Reinitialize DataTable with config below */
55
+ 'columnDefs': [
56
+ { 'orderable': true, 'targets': [0, 1, 2] },
57
+ { 'orderable': false, 'targets': [3, 4, 5, 6] }
58
+ ],
59
+ 'language': {
60
+ 'info': 'Showing _START_ to _END_ of _TOTAL_ exporters',
61
+ 'infoEmpty': 'No exporters to show',
62
+ 'infoFiltered': '(filtered from _MAX_ total exporters)',
63
+ 'lengthMenu': 'Show _MENU_ exporters'
64
+ }
65
+ })
66
+ })
67
+ </script>
@@ -0,0 +1,23 @@
1
+ <% provide :page_header do %>
2
+ <h1><span class="fa fa-edit" aria-hidden="true"></span> New Exporter</h1>
3
+ <% end %>
4
+
5
+ <div class="row">
6
+ <div class="col-md-12">
7
+ <div class="panel panel-default tabs">
8
+ <%= simple_form_for @exporter do |form| %>
9
+ <%= render 'form', exporter: @exporter, form: form %>
10
+ <div class="panel-footer">
11
+ <div class='pull-right'>
12
+ <%= form.button :submit, value: 'Create and Export', class: 'btn btn-primary' %>
13
+ |
14
+ <%= form.button :submit, value: 'Create', class: 'btn btn-primary' %>
15
+ |
16
+ <% cancel_path = form.object.persisted? ? exporter_path(form.object) : exporters_path %>
17
+ <%= link_to t('.cancel'), cancel_path, class: 'btn btn-default ' %>
18
+ </div>
19
+ </div>
20
+ <% end %>
21
+ </div>
22
+ </div>
23
+ </div>