From f3b3afbf78ae64f8158a883ca480a9c4f710ae75 Mon Sep 17 00:00:00 2001 From: Kevin De Pelseneer Date: Fri, 5 May 2023 11:03:27 +0200 Subject: [PATCH 01/54] Added the roo and roo-xls gems --- Gemfile | 4 ++++ Gemfile.lock | 18 ++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 7d70edf3a0..e612c80443 100644 --- a/Gemfile +++ b/Gemfile @@ -157,6 +157,10 @@ gem "net-http" gem "net-ftp" gem "uri", "0.10.0.2" +# Reading excel spreadsheets +gem "roo", "~> 2.10.0" +gem 'roo-xls', '~> 1.1' + group :production do gem 'passenger' end diff --git a/Gemfile.lock b/Gemfile.lock index 6085eeb01e..4289bb056d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -441,7 +441,6 @@ GEM nokogiri (~> 1) rake mini_mime (1.1.2) - mini_portile2 (2.8.1) minitest (5.18.0) minitest-reporters (1.5.0) ansi @@ -475,8 +474,7 @@ GEM net-protocol netrc (0.11.0) nio4r (2.5.8) - nokogiri (1.13.10) - mini_portile2 (~> 2.8.0) + nokogiri (1.13.10-x86_64-linux) racc (~> 1.4) nori (1.1.5) oauth2 (2.0.9) @@ -714,6 +712,13 @@ GEM ro-crate (0.5.1) addressable (>= 2.7, < 2.9) rubyzip (~> 2.0.0) + roo (2.10.0) + nokogiri (~> 1) + rubyzip (>= 1.3.0, < 3.0.0) + roo-xls (1.2.0) + nokogiri + roo (>= 2.0.0, < 3) + spreadsheet (> 0.9.0) rsolr (2.4.0) builder (>= 2.1.2) faraday (>= 0.9.0) @@ -745,6 +750,7 @@ GEM unicode-display_width (>= 1.4.0, < 3.0) rubocop-ast (1.15.1) parser (>= 3.0.1.1) + ruby-ole (1.2.12.2) ruby-prof (1.4.3) ruby-progressbar (1.11.0) ruby2_keywords (0.0.5) @@ -820,6 +826,8 @@ GEM sparql-client (3.2.0) net-http-persistent (~> 4.0, >= 4.0.1) rdf (~> 3.2) + spreadsheet (1.3.0) + ruby-ole sprockets (4.2.0) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) @@ -925,7 +933,7 @@ GEM rubyzip (~> 2.0.0) PLATFORMS - ruby + x86_64-linux DEPENDENCIES RedCloth (>= 4.3.0) @@ -1037,6 +1045,8 @@ DEPENDENCIES rmagick (= 2.15.2) ro-bundle (~> 0.3.0) ro-crate (~> 0.5.1) + roo (~> 2.10.0) + roo-xls (~> 1.1) rspec-rails (~> 5.1) rubocop ruby-prof From 8126b2aeab16b1d7d850fecfc65a0c1428fa12bf Mon Sep 17 00:00:00 2001 From: Kevin De Pelseneer Date: Mon, 8 May 2023 09:55:30 +0200 Subject: [PATCH 02/54] Working on uploading the samples via spreadsheet - added route to routes.rb - Extraction of sample information in the controller - Added a partial form with a button to upload the spreadsheet --- app/controllers/single_pages_controller.rb | 42 ++++++++++++++++++++++ app/views/isa_studies/_buttons.html.erb | 7 ++++ config/routes.rb | 1 + 3 files changed, 50 insertions(+) diff --git a/app/controllers/single_pages_controller.rb b/app/controllers/single_pages_controller.rb index c925cd6d6d..33dcb0416a 100644 --- a/app/controllers/single_pages_controller.rb +++ b/app/controllers/single_pages_controller.rb @@ -1,4 +1,7 @@ require 'isatab_converter' +require 'roo' +require 'roo-xls' + class SinglePagesController < ApplicationController include Seek::AssetsCommon include Seek::Sharing::SharingCommon @@ -59,6 +62,45 @@ def export_isa end end + def upload_samples + wb = Roo::Excelx.new(params[:file].path) + puts params + # Extract Samples metadata + puts wb.cell(2, 2, sheet = 'Metadata').to_i + puts wb.cell(5, 2, sheet = 'Metadata').to_i + puts wb.cell(8, 2, sheet = 'Metadata').to_i + + @study = Study.find(wb.cell(2, 2, sheet = 'Metadata').to_i) + @sample_type = SampleType.find(wb.cell(5, 2, sheet = 'Metadata').to_i) + @template = Template.find(wb.cell(8, 2, sheet = 'Metadata').to_i) + + sample_fields = wb.row(1, sheet = 'Samples') + samples_data = (2..wb.last_row(sheet = 'Samples')).map { |i| wb.row(i, sheet = 'Samples') } + + @excel_samples = samples_data.map do |excel_sample| + obj = {} + (0..sample_fields.size - 1).map do |i| + obj.merge!(sample_fields[i] => excel_sample[i]) + end + obj + end + + @existing_excel_samples = @excel_samples.map { |sample| sample unless sample['id'].nil? }.compact + @new_excel_samples = @excel_samples.map { |sample| sample if sample['id'].nil? }.compact + + @db_samples = @existing_excel_samples.map { |sample| JSON.parse(Sample.find(sample['id'])[:json_metadata]) } + + [@study, @sample_type, @template, @excel_samples, @existing_excel_samples, @new_excel_samples, @db_samples].each do |var| + puts '#' * 100 + puts var.inspect + end + puts '#' * 100 + + # respond_to do |format| + # format.html { redirect_to single_page_path(@study.projects.first) } + # end + end + private def set_up_instance_variable diff --git a/app/views/isa_studies/_buttons.html.erb b/app/views/isa_studies/_buttons.html.erb index 388e37f75e..720bec20f1 100644 --- a/app/views/isa_studies/_buttons.html.erb +++ b/app/views/isa_studies/_buttons.html.erb @@ -15,6 +15,13 @@ permissions||="loadBatchPermission('sampleDynamicTable',this)" +
+ <%= form_with url: upload_samples_single_page_url() , multipart: true do |form| %> + <%= form.file_field :file %> + <%= form.submit 'Upload' %> + <% end %> +
+ \ No newline at end of file + +async function handleUploadSubmit(e){ + const form = e.target; + const url = new URL(form.action); + let formData = new FormData(); + formData.append('file', fileUpload.files[0]); + + + $j.ajax({ + type: 'POST', + url: url, + data: formData, + dataType: 'html', + processData: false, + contentType: false, + enctype: 'multipart/form-data', + success: function(response){ + $j('#upload-excel-modal').modal('show').focus(); + $j('#upload-excel').html(response); + }, + error: function(err){ + alert(`The following error occurred!\n${err}`); + } + }); + e.preventDefault(); +} + const uploadExcelForm = document.getElementById("upload_excel_form"); + uploadExcelForm.addEventListener('submit', handleUploadSubmit); + From f8128b3683255a9f991f051d65bbb07f335535c3 Mon Sep 17 00:00:00 2001 From: Kevin De Pelseneer Date: Fri, 16 Jun 2023 17:41:46 +0200 Subject: [PATCH 05/54] Added a modal form for the overview of the upload actions --- .../sample_upload_content.html.erb | 134 ++++++++++++++++++ app/views/single_pages/show.html.erb | 19 ++- 2 files changed, 147 insertions(+), 6 deletions(-) create mode 100644 app/views/single_pages/sample_upload_content.html.erb diff --git a/app/views/single_pages/sample_upload_content.html.erb b/app/views/single_pages/sample_upload_content.html.erb new file mode 100644 index 0000000000..572a3637a5 --- /dev/null +++ b/app/views/single_pages/sample_upload_content.html.erb @@ -0,0 +1,134 @@ +
+ <%= folding_panel("General Inforamtion", true, :id => "general-information-panel") do %> + <% [@study, @sample_type, @template]. map do | entity | %> +

<%= entity.class.to_s.singularize %>

+

ID: <%= entity.id%>

+

UUID: <%= entity.uuid %>

+

Title: <%= entity.title %>

+
+ <% end %> + <% end %> + + <% unless @new_samples.nil? or @new_samples.compact == [] %> + <%= folding_panel("New Samples #{@new_samples.size}", true, :id => "new-samples-panel", :body_options => {:id => "new-samples-panel-content"}, + :help_text => "These samples have been detected as new samples and will be created.") do %> +
+ + + + <% for key in @new_samples[0].keys %> + + <% end %> + + <% for new_sample in @new_samples %> + <% new_sample_id = UUID.generate %> + + + <% new_sample.map do |key, val| %> + <% val = '' if key =='id' %> + + <% end %> + + <% end %> +
<%= key unless %w[uuid].include?(key) %>
<%= val unless %w[uuid].include?(key) %>
+
+ <% end %> +<% end %> + + <% unless @update_samples.nil? or @update_samples.compact == [] %> + <%= folding_panel("Samples to Update #{@update_samples.size}", true, :id => "existing-samples-panel", :body_options => {:id => "existing-samples-panel-content"}, + :help_text => "These samples were detected existing samples and will be updated.") do %> +
+ + + + <% for key in @update_samples[0].keys %> + + <% end %> + + <% for update_sample in @update_samples %> + ' > + <% db_sample = @db_samples.select { |s| s['id'] == update_sample['id'] }.first %> + + <% update_sample.map do |key, val| %> + + <% end %> + + ' > + <% db_sample.map do |key, val| %> + + <% end %> + + <% end %> +
<%= key unless key == 'uuid' %>
+ <%= val unless key == 'uuid' %> +
+ <%= val unless key == 'uuid' %> +
+
+ <% end %> +<% end %> + +<% unless @possible_duplicates.nil? or @possible_duplicates.compact == [] %> + <%= folding_panel("Possible Duplicates #{@possible_duplicates.size}", true, :id => "existing-samples-panel", :body_options => {:id => "existing-samples-panel-content"}, + :help_text => "These new samples have been matched to already existing samples.") do %> +
+ + + + <% for key in @possible_duplicates[0].keys %> + + <% end %> + + <% for dupl_sample in @possible_duplicates %> + ' > + + <% dupl_sample.map do |key, val| %> + <% val = '' if key =='id' %> + + <% end %> + ' class="danger"> + <% dupl_sample['duplicate'].map do |key, val| %> + + <% end %> + + + <% end %> +
+ <%= key unless %w[uuid duplicate].include?(key) %> +
+ + + <%= val unless %w[uuid duplicate].include?(key) %> +
+ <%= val unless %w[uuid duplicate].include?(key) %> +
+
+ <% end %> + <% end %> + + + <%= submit_tag "Next", data: {disable_with: 'Next'}, :class => 'btn btn-primary', onclick: "" %> +
+ diff --git a/app/views/single_pages/show.html.erb b/app/views/single_pages/show.html.erb index 97cc879676..29c6185021 100644 --- a/app/views/single_pages/show.html.erb +++ b/app/views/single_pages/show.html.erb @@ -16,7 +16,7 @@
  • Assay
  • - Toggle: + Toggle: @@ -56,11 +56,18 @@ <% end %> <% end %> + <%= modal(id: 'upload-excel-modal', size: 'xl') do %> + <%= modal_header("Upload from spreadsheet") %> + <%= modal_body do %> +
    ...
    + <% end %> + <% end %> +
    \ No newline at end of file + + From bcd77623a45a9623ca12b064e0a625ba7436eff5 Mon Sep 17 00:00:00 2001 From: Kevin De Pelseneer Date: Mon, 26 Jun 2023 21:15:42 +0200 Subject: [PATCH 06/54] Added `project` and changed `db_samples` to match the samples from the database the current user has at least editing authorization for. --- app/controllers/single_pages_controller.rb | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/app/controllers/single_pages_controller.rb b/app/controllers/single_pages_controller.rb index 613446b6e4..372b8a9452 100644 --- a/app/controllers/single_pages_controller.rb +++ b/app/controllers/single_pages_controller.rb @@ -25,7 +25,8 @@ def show def index; end def project_folders - return if !Seek::Config.project_single_page_folders_enabled + return unless Seek::Config.project_single_page_folders_enabled + project_folders = ProjectFolder.root_folders(@project) if project_folders.empty? project_folders = ProjectFolder.initialize_default_folders(@project) @@ -73,6 +74,7 @@ def upload_samples @study = Study.find(study_id) @sample_type = SampleType.find(sample_type_id) @template = Template.find(template_id) + @project = @study.projects.first # In Single Page a study can only belong to one project sample_fields = wb.row(1, sheet = 'Samples').map { |field| field.sub(' *', '') } samples_data = (2..wb.last_row(sheet = 'Samples')).map { |i| wb.row(i, sheet = 'Samples') } @@ -88,11 +90,10 @@ def upload_samples @existing_excel_samples = @excel_samples.map { |sample| sample unless sample['id'].nil? }.compact @new_excel_samples = @excel_samples.map { |sample| sample if sample['id'].nil? }.compact - @db_samples = @existing_excel_samples.map do |sample| - raw_sample = Sample.find(sample['id']) - attributes = JSON.parse(raw_sample[:json_metadata]) - { 'id' => raw_sample.id, - 'uuid' => raw_sample.uuid }.merge(attributes) + @db_samples = @sample_type.samples&.authorized_for(:edit)&.map do |sample| + attributes = JSON.parse(sample[:json_metadata]) + { 'id' => sample.id, + 'uuid' => sample.uuid }.merge(attributes) end # Determine whether samples have been modified or not @@ -120,15 +121,15 @@ def upload_samples @new_excel_samples.map do |nes| is_duplicate = true - @existing_excel_samples.map do |ees| - ees.map do |k, v| + @db_samples.map do |dbs| + dbs.map do |k, v| unless %w[id uuid].include?(k) is_duplicate = (nes[k] == v) break unless is_duplicate end end if is_duplicate - @possible_duplicates.append(nes.merge({ 'duplicate' => ees })) + @possible_duplicates.append(nes.merge({ 'duplicate' => dbs })) break end end From 2cdc97b2f8fe065c79595efd18bc146f2d0ef2df Mon Sep 17 00:00:00 2001 From: Kevin De Pelseneer Date: Mon, 26 Jun 2023 21:17:09 +0200 Subject: [PATCH 07/54] Implemented javascript functions to submit samples to update and samples to create. --- .../sample_upload_content.html.erb | 138 ++++++++++++++++-- 1 file changed, 126 insertions(+), 12 deletions(-) diff --git a/app/views/single_pages/sample_upload_content.html.erb b/app/views/single_pages/sample_upload_content.html.erb index 572a3637a5..2ead616ef0 100644 --- a/app/views/single_pages/sample_upload_content.html.erb +++ b/app/views/single_pages/sample_upload_content.html.erb @@ -110,6 +110,7 @@ <%= submit_tag "Next", data: {disable_with: 'Next'}, :class => 'btn btn-primary', onclick: "" %> + From bcd9f56d21f22b19f858e23657fb262420e91e19 Mon Sep 17 00:00:00 2001 From: Kevin De Pelseneer Date: Mon, 26 Jun 2023 21:20:00 +0200 Subject: [PATCH 08/54] Changed the sample upload modal: - Removed trailing `\n` from cells - Added more information to 'General Information' pane --- .../sample_upload_content.html.erb | 90 +++++++++++-------- 1 file changed, 55 insertions(+), 35 deletions(-) diff --git a/app/views/single_pages/sample_upload_content.html.erb b/app/views/single_pages/sample_upload_content.html.erb index 2ead616ef0..48636bebc9 100644 --- a/app/views/single_pages/sample_upload_content.html.erb +++ b/app/views/single_pages/sample_upload_content.html.erb @@ -1,10 +1,24 @@
    - <%= folding_panel("General Inforamtion", true, :id => "general-information-panel") do %> - <% [@study, @sample_type, @template]. map do | entity | %> -

    <%= entity.class.to_s.singularize %>

    -

    ID: <%= entity.id%>

    -

    UUID: <%= entity.uuid %>

    -

    Title: <%= entity.title %>

    + <%= folding_panel("General Information", true, :id => "general-information-panel") do %> + <% [@project, @study, @sample_type, @template]. map do | asset | %> + <% asset_name = asset.class.to_s.singularize %> +

    <%= asset_name %>

    +

    ID: <%= asset.id%>

    +

    UUID: <%= asset.uuid %>

    +

    Title: <%= asset.title %>

    + <% if asset_name == "Project"%> + <% if current_user.person.member_of?(asset)%> +

    <%= current_user.person.name %> is member of this project:

    + <% else %> +

    <%= current_user.person.name %> is member of this project:

    + <% end %> + <% else %> + <% if asset.can_manage?%> +

    <%= current_user.person.name %> can manage:

    + <% else %> +

    <%= current_user.person.name %> can manage:

    + <% end %> + <% end %>
    <% end %> <% end %> @@ -13,11 +27,13 @@ <%= folding_panel("New Samples #{@new_samples.size}", true, :id => "new-samples-panel", :body_options => {:id => "new-samples-panel-content"}, :help_text => "These samples have been detected as new samples and will be created.") do %>
    - +
    <% for key in @new_samples[0].keys %> - + <% unless key == 'uuid' %> + + <% end %> <% end %> <% for new_sample in @new_samples %> @@ -26,7 +42,9 @@ <% new_sample.map do |key, val| %> <% val = '' if key =='id' %> - + <% unless key == 'uuid' %> + + <% end %> <% end %> <% end %> @@ -43,24 +61,26 @@ <% for key in @update_samples[0].keys %> - + <% unless key == 'uuid' %> + + <% end %> <% end %> <% for update_sample in @update_samples %> - ' > + ' > <% db_sample = @db_samples.select { |s| s['id'] == update_sample['id'] }.first %> <% update_sample.map do |key, val| %> - + <% unless key == 'uuid' %> + + <% end %> <% end %> - ' > + ' > <% db_sample.map do |key, val| %> - + <% unless key == 'uuid' %> + + <% end %> <% end %> <% end %> @@ -77,27 +97,25 @@ <% for key in @possible_duplicates[0].keys %> - + <% unless %w[uuid duplicate].include?(key) %> + + <% end %> <% end %> <% for dupl_sample in @possible_duplicates %> ' > - - <% dupl_sample.map do |key, val| %> - <% val = '' if key =='id' %> - - <% end %> + + <% dupl_sample.map do |key, val| %> + <% val = '' if key =='id' %> + <% unless %w[uuid duplicate].include?(key) %> + + <% end %> + <% end %> ' class="danger"> <% dupl_sample['duplicate'].map do |key, val| %> - + <% unless %w[uuid duplicate].include?(key) %> + + <% end %> <% end %> @@ -105,10 +123,12 @@
    <%= key unless %w[uuid].include?(key) %><%= key %>
    <%= val unless %w[uuid].include?(key) %><%= val %>
    <%= key unless key == 'uuid' %><%= key %>
    - <%= val unless key == 'uuid' %> - ' ><%= val %>
    - <%= val unless key == 'uuid' %> - <%= val %>
    - <%= key unless %w[uuid duplicate].include?(key) %> - <%= key %>
    - - - <%= val unless %w[uuid duplicate].include?(key) %> - ' ><%= val %>
    - <%= val unless %w[uuid duplicate].include?(key) %> - <%= val %>
    <% end %> - <% end %> +<% end %> +
    - <%= submit_tag "Next", data: {disable_with: 'Next'}, :class => 'btn btn-primary', onclick: "" %> + <%= submit_tag "Next", data: {disable_with: 'Next'}, :class => 'btn btn-primary', onclick: "submitUpload()" %> + <%= submit_tag "Cancel", data: {id: 'cancelModalUploadExcel'}, :class => 'btn btn-secondary', onclick: "closeModalForm()" %>
    \ No newline at end of file + +async function handleUploadSubmit(e){ + const form = e.target; + const url = new URL(form.action); + let formData = new FormData(); + formData.append('file', fileUpload.files[0]); + + + $j.ajax({ + type: 'POST', + url: url, + data: formData, + dataType: 'html', + processData: false, + contentType: false, + enctype: 'multipart/form-data', + success: function(response){ + $j('#upload-excel-modal').modal('show').focus(); + $j('#upload-excel').html(response); + }, + error: function(err){ + alert(`The following error occurred!\n${err}`); + } + }); + e.preventDefault(); +} + const uploadExcelForm = document.getElementById("upload_excel_form"); + uploadExcelForm.addEventListener('submit', handleUploadSubmit); + From d851c6188ad962871c0b96afde059f581d106768 Mon Sep 17 00:00:00 2001 From: Kevin De Pelseneer Date: Fri, 16 Jun 2023 17:41:46 +0200 Subject: [PATCH 15/54] Added a modal form for the overview of the upload actions --- .../sample_upload_content.html.erb | 134 ++++++++++++++++++ app/views/single_pages/show.html.erb | 7 + 2 files changed, 141 insertions(+) create mode 100644 app/views/single_pages/sample_upload_content.html.erb diff --git a/app/views/single_pages/sample_upload_content.html.erb b/app/views/single_pages/sample_upload_content.html.erb new file mode 100644 index 0000000000..572a3637a5 --- /dev/null +++ b/app/views/single_pages/sample_upload_content.html.erb @@ -0,0 +1,134 @@ +
    + <%= folding_panel("General Inforamtion", true, :id => "general-information-panel") do %> + <% [@study, @sample_type, @template]. map do | entity | %> +

    <%= entity.class.to_s.singularize %>

    +

    ID: <%= entity.id%>

    +

    UUID: <%= entity.uuid %>

    +

    Title: <%= entity.title %>

    +
    + <% end %> + <% end %> + + <% unless @new_samples.nil? or @new_samples.compact == [] %> + <%= folding_panel("New Samples #{@new_samples.size}", true, :id => "new-samples-panel", :body_options => {:id => "new-samples-panel-content"}, + :help_text => "These samples have been detected as new samples and will be created.") do %> +
    + + + + <% for key in @new_samples[0].keys %> + + <% end %> + + <% for new_sample in @new_samples %> + <% new_sample_id = UUID.generate %> + + + <% new_sample.map do |key, val| %> + <% val = '' if key =='id' %> + + <% end %> + + <% end %> +
    <%= key unless %w[uuid].include?(key) %>
    <%= val unless %w[uuid].include?(key) %>
    +
    + <% end %> +<% end %> + + <% unless @update_samples.nil? or @update_samples.compact == [] %> + <%= folding_panel("Samples to Update #{@update_samples.size}", true, :id => "existing-samples-panel", :body_options => {:id => "existing-samples-panel-content"}, + :help_text => "These samples were detected existing samples and will be updated.") do %> +
    + + + + <% for key in @update_samples[0].keys %> + + <% end %> + + <% for update_sample in @update_samples %> + ' > + <% db_sample = @db_samples.select { |s| s['id'] == update_sample['id'] }.first %> + + <% update_sample.map do |key, val| %> + + <% end %> + + ' > + <% db_sample.map do |key, val| %> + + <% end %> + + <% end %> +
    <%= key unless key == 'uuid' %>
    + <%= val unless key == 'uuid' %> +
    + <%= val unless key == 'uuid' %> +
    +
    + <% end %> +<% end %> + +<% unless @possible_duplicates.nil? or @possible_duplicates.compact == [] %> + <%= folding_panel("Possible Duplicates #{@possible_duplicates.size}", true, :id => "existing-samples-panel", :body_options => {:id => "existing-samples-panel-content"}, + :help_text => "These new samples have been matched to already existing samples.") do %> +
    + + + + <% for key in @possible_duplicates[0].keys %> + + <% end %> + + <% for dupl_sample in @possible_duplicates %> + ' > + + <% dupl_sample.map do |key, val| %> + <% val = '' if key =='id' %> + + <% end %> + ' class="danger"> + <% dupl_sample['duplicate'].map do |key, val| %> + + <% end %> + + + <% end %> +
    + <%= key unless %w[uuid duplicate].include?(key) %> +
    + + + <%= val unless %w[uuid duplicate].include?(key) %> +
    + <%= val unless %w[uuid duplicate].include?(key) %> +
    +
    + <% end %> + <% end %> + + + <%= submit_tag "Next", data: {disable_with: 'Next'}, :class => 'btn btn-primary', onclick: "" %> +
    + diff --git a/app/views/single_pages/show.html.erb b/app/views/single_pages/show.html.erb index 327d96e652..29c6185021 100644 --- a/app/views/single_pages/show.html.erb +++ b/app/views/single_pages/show.html.erb @@ -56,6 +56,13 @@ <% end %> <% end %> + <%= modal(id: 'upload-excel-modal', size: 'xl') do %> + <%= modal_header("Upload from spreadsheet") %> + <%= modal_body do %> +
    ...
    + <% end %> + <% end %> + From ddaba00e1cf6b967b0654298c2b00367e830a673 Mon Sep 17 00:00:00 2001 From: Kevin De Pelseneer Date: Mon, 26 Jun 2023 21:20:00 +0200 Subject: [PATCH 18/54] Changed the sample upload modal: - Removed trailing `\n` from cells - Added more information to 'General Information' pane --- .../sample_upload_content.html.erb | 90 +++++++++++-------- 1 file changed, 55 insertions(+), 35 deletions(-) diff --git a/app/views/single_pages/sample_upload_content.html.erb b/app/views/single_pages/sample_upload_content.html.erb index 2ead616ef0..48636bebc9 100644 --- a/app/views/single_pages/sample_upload_content.html.erb +++ b/app/views/single_pages/sample_upload_content.html.erb @@ -1,10 +1,24 @@
    - <%= folding_panel("General Inforamtion", true, :id => "general-information-panel") do %> - <% [@study, @sample_type, @template]. map do | entity | %> -

    <%= entity.class.to_s.singularize %>

    -

    ID: <%= entity.id%>

    -

    UUID: <%= entity.uuid %>

    -

    Title: <%= entity.title %>

    + <%= folding_panel("General Information", true, :id => "general-information-panel") do %> + <% [@project, @study, @sample_type, @template]. map do | asset | %> + <% asset_name = asset.class.to_s.singularize %> +

    <%= asset_name %>

    +

    ID: <%= asset.id%>

    +

    UUID: <%= asset.uuid %>

    +

    Title: <%= asset.title %>

    + <% if asset_name == "Project"%> + <% if current_user.person.member_of?(asset)%> +

    <%= current_user.person.name %> is member of this project:

    + <% else %> +

    <%= current_user.person.name %> is member of this project:

    + <% end %> + <% else %> + <% if asset.can_manage?%> +

    <%= current_user.person.name %> can manage:

    + <% else %> +

    <%= current_user.person.name %> can manage:

    + <% end %> + <% end %>
    <% end %> <% end %> @@ -13,11 +27,13 @@ <%= folding_panel("New Samples #{@new_samples.size}", true, :id => "new-samples-panel", :body_options => {:id => "new-samples-panel-content"}, :help_text => "These samples have been detected as new samples and will be created.") do %>
    - +
    <% for key in @new_samples[0].keys %> - + <% unless key == 'uuid' %> + + <% end %> <% end %> <% for new_sample in @new_samples %> @@ -26,7 +42,9 @@ <% new_sample.map do |key, val| %> <% val = '' if key =='id' %> - + <% unless key == 'uuid' %> + + <% end %> <% end %> <% end %> @@ -43,24 +61,26 @@ <% for key in @update_samples[0].keys %> - + <% unless key == 'uuid' %> + + <% end %> <% end %> <% for update_sample in @update_samples %> - ' > + ' > <% db_sample = @db_samples.select { |s| s['id'] == update_sample['id'] }.first %> <% update_sample.map do |key, val| %> - + <% unless key == 'uuid' %> + + <% end %> <% end %> - ' > + ' > <% db_sample.map do |key, val| %> - + <% unless key == 'uuid' %> + + <% end %> <% end %> <% end %> @@ -77,27 +97,25 @@ <% for key in @possible_duplicates[0].keys %> - + <% unless %w[uuid duplicate].include?(key) %> + + <% end %> <% end %> <% for dupl_sample in @possible_duplicates %> ' > - - <% dupl_sample.map do |key, val| %> - <% val = '' if key =='id' %> - - <% end %> + + <% dupl_sample.map do |key, val| %> + <% val = '' if key =='id' %> + <% unless %w[uuid duplicate].include?(key) %> + + <% end %> + <% end %> ' class="danger"> <% dupl_sample['duplicate'].map do |key, val| %> - + <% unless %w[uuid duplicate].include?(key) %> + + <% end %> <% end %> @@ -105,10 +123,12 @@
    <%= key unless %w[uuid].include?(key) %><%= key %>
    <%= val unless %w[uuid].include?(key) %><%= val %>
    <%= key unless key == 'uuid' %><%= key %>
    - <%= val unless key == 'uuid' %> - ' ><%= val %>
    - <%= val unless key == 'uuid' %> - <%= val %>
    - <%= key unless %w[uuid duplicate].include?(key) %> - <%= key %>
    - - - <%= val unless %w[uuid duplicate].include?(key) %> - ' ><%= val %>
    - <%= val unless %w[uuid duplicate].include?(key) %> - <%= val %>
    <% end %> - <% end %> +<% end %> +
    - <%= submit_tag "Next", data: {disable_with: 'Next'}, :class => 'btn btn-primary', onclick: "" %> + <%= submit_tag "Next", data: {disable_with: 'Next'}, :class => 'btn btn-primary', onclick: "submitUpload()" %> + <%= submit_tag "Cancel", data: {id: 'cancelModalUploadExcel'}, :class => 'btn btn-secondary', onclick: "closeModalForm()" %>
    <% end %> diff --git a/app/views/isa_studies/_buttons.html.erb b/app/views/isa_studies/_buttons.html.erb index 350bf0ffc4..61a928c0b9 100644 --- a/app/views/isa_studies/_buttons.html.erb +++ b/app/views/isa_studies/_buttons.html.erb @@ -6,6 +6,7 @@ delete||="SampleSetAsDeleted()" save||="SampleSave()" permissions||="loadBatchPermission('sampleDynamicTable',this)" exportToExcel||="sampleExportExcel()" +uploadExcel||="studySampleUploadExcel()" %>
    @@ -18,17 +19,15 @@ exportToExcel||="sampleExportExcel()"
    -
    -
    - -
    -
    - -
    -
    - -
    -
    +
    + +
    +
    + +
    +
    + +
    diff --git a/app/views/isa_studies/_source_material.html.erb b/app/views/isa_studies/_source_material.html.erb index f534cba03f..7a2ecb74bc 100644 --- a/app/views/isa_studies/_source_material.html.erb +++ b/app/views/isa_studies/_source_material.html.erb @@ -11,7 +11,8 @@ <%= render partial: 'isa_studies/buttons', locals:{ add_row: "SourceAddNewRow()", paste_cb: "SourcePasteFromClipboard()", delete: "SourceSetAsDeleted()", save: "SourceSave()", -permissions: "loadBatchPermission('sourceDynamicTable',this)", exportToExcel: "sourceExportExcel()" } %> +permissions: "loadBatchPermission('sourceDynamicTable',this)", exportToExcel: "sourceExportExcel()", +uploadExcel: 'sourceUploadExcel()', sample_type_id: sample_type&.id} %> <% if sample_type %> <% end %> diff --git a/app/views/isa_studies/_study_samples.html.erb b/app/views/isa_studies/_study_samples.html.erb index 4b206980c1..3c339dac57 100644 --- a/app/views/isa_studies/_study_samples.html.erb +++ b/app/views/isa_studies/_study_samples.html.erb @@ -9,7 +9,7 @@ -<%= render partial: 'isa_studies/buttons' %> +<%= render partial: 'isa_studies/buttons', locals: {uploadExcel: "studySampleUploadExcel()", sample_type_id: sample_type&.id} %> <% if sample_type %> <% end %> diff --git a/config/routes.rb b/config/routes.rb index afdc8e184c..3e65e18022 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -750,7 +750,6 @@ member do get :dynamic_table_data get :export_isa, action: :export_isa - post :upload_samples, action: :upload_samples end collection do get :batch_sharing_permission_preview @@ -758,6 +757,7 @@ post :batch_sharing_permission_changed post :export_to_excel, action: :export_to_excel get :download_samples_excel, action: :download_samples_excel + post :upload_samples, action: :upload_samples end end From d0598ced10252ebb42a27b1428f66833815c1bb5 Mon Sep 17 00:00:00 2001 From: Kevin De Pelseneer Date: Fri, 7 Jul 2023 09:25:05 +0200 Subject: [PATCH 24/54] Fixed notice when error occurs --- app/assets/javascripts/single_page/index.js.erb | 2 +- app/controllers/single_pages_controller.rb | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/single_page/index.js.erb b/app/assets/javascripts/single_page/index.js.erb index c17e1b238d..ee554f2d3b 100644 --- a/app/assets/javascripts/single_page/index.js.erb +++ b/app/assets/javascripts/single_page/index.js.erb @@ -296,7 +296,7 @@ async function handleUploadSubmit(formData){ $j('#upload-excel').html(response); }, error: function(err){ - alert(`The following error occurred!\n${err}`); + location.reload(); // Page needs reloading for the notice message to appear } }); } diff --git a/app/controllers/single_pages_controller.rb b/app/controllers/single_pages_controller.rb index 49351bcf17..ecd63eb84f 100644 --- a/app/controllers/single_pages_controller.rb +++ b/app/controllers/single_pages_controller.rb @@ -213,7 +213,10 @@ def upload_samples format.json { render json: { uploadData: upload_data } } format.html { render 'single_pages/sample_upload_content', { layout: false } } end - end + rescue StandardError => e + flash[:error] = e.message + redirect_to single_page_path(@study.project_ids.first), status: :bad_request +end private From 546c861a6d11f555453583725e73892c8e215f03 Mon Sep 17 00:00:00 2001 From: Kevin De Pelseneer Date: Fri, 7 Jul 2023 13:14:01 +0200 Subject: [PATCH 25/54] Update counter when a sample is removed. --- .../sample_upload_content.html.erb | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/app/views/single_pages/sample_upload_content.html.erb b/app/views/single_pages/sample_upload_content.html.erb index 3aec638b0f..5a459ad02d 100644 --- a/app/views/single_pages/sample_upload_content.html.erb +++ b/app/views/single_pages/sample_upload_content.html.erb @@ -28,7 +28,7 @@ <% end %> <% unless @new_samples.nil? or @new_samples.compact.none? %> - <%= folding_panel("New Samples #{@new_samples.size}", true, :id => "new-samples-panel", :body_options => {:id => "new-samples-panel-content"}, + <%= folding_panel("New Samples #{@new_samples.size}", true, :id => "new-samples-panel", :body_options => {:id => "new-samples-panel-content"}, :help_text => "These samples have been detected as new samples and will be created.") do %>
    @@ -58,7 +58,7 @@ <% end %> <% unless @update_samples.nil? or @update_samples.compact.none? %> - <%= folding_panel("Samples to Update #{@update_samples.size}", true, :id => "existing-samples-panel", :body_options => {:id => "existing-samples-panel-content"}, + <%= folding_panel("Samples to Update #{@update_samples.size}", true, :id => "existing-samples-panel", :body_options => {:id => "existing-samples-panel-content"}, :help_text => "These samples were detected existing samples and will be updated.") do %>
    @@ -94,7 +94,7 @@ <% end %> <% unless @possible_duplicates.nil? or @possible_duplicates.compact.none? %> - <%= folding_panel("Possible Duplicates #{@possible_duplicates.size}", true, :id => "existing-samples-panel", :body_options => {:id => "existing-samples-panel-content"}, + <%= folding_panel("Possible Duplicates #{@possible_duplicates.size}", true, :id => "existing-samples-panel", :body_options => {:id => "existing-samples-panel-content"}, :help_text => "These new samples have been matched to already existing samples.") do %>
    @@ -145,7 +145,20 @@