From e1bf41fb6c8e8f1b798c4a5aa0d1cf6f71bbfd17 Mon Sep 17 00:00:00 2001 From: Kevin De Pelseneer Date: Thu, 14 Dec 2023 15:21:44 +0100 Subject: [PATCH 01/24] Add allow free text fields to template attributes --- .../templates/_template_attribute_form.html.erb | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/app/views/templates/_template_attribute_form.html.erb b/app/views/templates/_template_attribute_form.html.erb index e5a7d3b6ec..ce835677d7 100644 --- a/app/views/templates/_template_attribute_form.html.erb +++ b/app/views/templates/_template_attribute_form.html.erb @@ -17,6 +17,7 @@ <% isa_tag_id = template_attribute&.isa_tag_id %> <% isa_tag_title = template_attribute&.isa_tag&.title %> <% is_parent_attribute ||= false %> +<% allow_cv_free_text = template_attribute&.allow_cv_free_text || false %> @@ -45,17 +46,25 @@ <%= select_tag "#{field_name_prefix}[sample_attribute_type_id]", options_for_select(SampleAttributeType.all.sort_by(&:title).sort_by { |t| t.default? ? 0 : 1 }.map do |t| - [t.title, t.id,{'data-is-cv': t.controlled_vocab?,'data-is-seek-sample': t.seek_sample? || t.seek_sample_multi? }] + [t.title, t.id,{'data-use-cv': t.controlled_vocab?,'data-is-seek-sample': t.seek_sample? || t.seek_sample_multi? }] end, attribute_type_id), class: 'form-control sample-type-attribute-type', data: {attr: "type"} %> -
+

<%= select_tag "#{field_name_prefix}[sample_controlled_vocab_id]", options_for_select(SampleControlledVocab.all.map { |scv| [scv.title, scv.id, {'data-editable': scv.can_edit?}] }, sample_controlled_vocab_id),include_blank: true, class: 'form-control controlled-vocab-selection', data: {attr: "cv_id"} %> +
+ +
+ <%= button_link_to('Edit', 'edit', '#', class:'cv-edit-button', disabled: true, target: :_blank) %> <%= create_sample_controlled_vocab_modal_button %> From 23f0f1adb7dcae01cbf68fe02b9155e55e1fdae3 Mon Sep 17 00:00:00 2001 From: Kevin De Pelseneer Date: Thu, 14 Dec 2023 15:22:15 +0100 Subject: [PATCH 02/24] add allow_free_cv_text param to templates controller --- app/controllers/templates_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/templates_controller.rb b/app/controllers/templates_controller.rb index b75b1d2743..b5e12e3b07 100644 --- a/app/controllers/templates_controller.rb +++ b/app/controllers/templates_controller.rb @@ -157,7 +157,7 @@ def template_params template_attributes_attributes: %i[id title pos required description sample_attribute_type_id isa_tag_id is_title sample_controlled_vocab_id pid - unit_id _destroy] }) + unit_id _destroy allow_cv_free_text] }) end def find_template From 230e15d38f79ecf1535385e6458d752ec8988ac9 Mon Sep 17 00:00:00 2001 From: Kevin De Pelseneer Date: Thu, 14 Dec 2023 16:58:08 +0100 Subject: [PATCH 03/24] add allow_cv_free_text attribute --- app/helpers/templates_helper.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/helpers/templates_helper.rb b/app/helpers/templates_helper.rb index 0e2b451828..cafdd9f49f 100644 --- a/app/helpers/templates_helper.rb +++ b/app/helpers/templates_helper.rb @@ -75,6 +75,7 @@ def map_template_attributes(attribute) attribute_type_id: attribute.sample_attribute_type_id, data_type: SampleAttributeType.find(attribute.sample_attribute_type_id)&.title, cv_id: attribute.sample_controlled_vocab_id, + allow_cv_free_text: attribute.allow_cv_free_text, title: attribute.title, is_title: attribute.is_title, short_name: attribute.short_name, From 1200d27e0ef481a426b7ec3f946e0e2013cd72b9 Mon Sep 17 00:00:00 2001 From: Kevin De Pelseneer Date: Thu, 14 Dec 2023 17:53:41 +0100 Subject: [PATCH 04/24] add allow_cv_free_text in templates js --- app/assets/javascripts/templates.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/templates.js b/app/assets/javascripts/templates.js index 11bea4dea6..fd3c71d7e5 100644 --- a/app/assets/javascripts/templates.js +++ b/app/assets/javascripts/templates.js @@ -11,7 +11,7 @@ Templates.init = function (elem) { const columnDefs = [ { orderable: false, targets: [0, 7, 11] }, { - targets: [3, 4, 9, 10], + targets: [3, 4, 5, 10, 11], visible: false, searchable: false }, @@ -33,6 +33,7 @@ Templates.init = function (elem) { { title: "Description", width: "40%" }, { title: "attribute_type_id" }, { title: "cv_id" }, + { title: "allow_cv_free_text" }, { title: "Unit", width: "5%" }, { title: "Data type", width: "10%" }, { @@ -115,6 +116,7 @@ Templates.mapData = (data) => item.description, item.attribute_type_id, item.cv_id, + item.allow_cv_free_text, item.unit_id, item.data_type, item.is_title, @@ -232,17 +234,17 @@ const applyTemplate = () => { index++; newRow = $j(newRow.replace(/replace-me/g, index)); - $j(newRow).find('[data-attr="required"]').prop("checked", row[0]); $j(newRow).find('[data-attr="title"]').val(row[1]); $j(newRow).find('[data-attr="description"]').val(row[2]); $j(newRow).find('[data-attr="type"]').val(row[3]); $j(newRow).find('[data-attr="cv_id"]').val(row[4]); - $j(newRow).find('[data-attr="unit"]').val(row[5]); - $j(newRow).find(".sample-type-is-title").prop("checked", row[7]); - $j(newRow).find('[data-attr="pid"]').val(row[8]); - $j(newRow).find('[data-attr="isa_tag_id"]').val(row[10]); - $j(newRow).find('[data-attr="isa_tag_title"]').val(row[10]); + $j(newRow).find('[data-attr="allow_cv_free_text"]').prop("checked", row[5]); + $j(newRow).find('[data-attr="unit"]').val(row[6]); + $j(newRow).find(".sample-type-is-title").prop("checked", row[8]); + $j(newRow).find('[data-attr="pid"]').val(row[9]); + $j(newRow).find('[data-attr="isa_tag_id"]').val(row[11]); + $j(newRow).find('[data-attr="isa_tag_title"]').val(row[11]); $j(newRow).find('[data-attr="isa_tag_title"]').attr('disabled', true); // Show the CV block if cv_id is not empty From 6cff2e89eefc803fa7d3c5ea52c767e3623f3c25 Mon Sep 17 00:00:00 2001 From: Kevin De Pelseneer Date: Thu, 14 Dec 2023 17:54:54 +0100 Subject: [PATCH 05/24] add allow_cv_free_text dat attribute --- app/views/sample_types/_sample_attribute_form.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/sample_types/_sample_attribute_form.html.erb b/app/views/sample_types/_sample_attribute_form.html.erb index 8aa5493470..e97eef7c7a 100644 --- a/app/views/sample_types/_sample_attribute_form.html.erb +++ b/app/views/sample_types/_sample_attribute_form.html.erb @@ -73,7 +73,7 @@
From 6cf94836b690f6e4c539a19501a985b45e59566c Mon Sep 17 00:00:00 2001 From: Kevin De Pelseneer Date: Fri, 15 Dec 2023 11:03:11 +0100 Subject: [PATCH 06/24] Simplify filtering of ISA tags --- app/views/isa_studies/_sample_types_form.html.erb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/views/isa_studies/_sample_types_form.html.erb b/app/views/isa_studies/_sample_types_form.html.erb index 8889467eb3..d8f94b527b 100644 --- a/app/views/isa_studies/_sample_types_form.html.erb +++ b/app/views/isa_studies/_sample_types_form.html.erb @@ -4,6 +4,7 @@ <% add_attribute_row_id = 'add-attribute-row' + id_suffix %> <% main_field_name = id_suffix[1..-1] %> <% isa_element ||= "study" %> +<% sample_type_level = @isa_assay.sample_type&.isa_template&.level %> <%= f.fields_for main_field_name, sample_type do |field| %> @@ -139,10 +140,7 @@ $j('#attribute-table_sample_collection_sample_type').find('tr.sample-attribute [data-attr="isa_tag_title"]').attr('disabled', true); // Filter ISA tags for new rows - updateIsaTagSelect("study source", "#new-attribute-row_source_sample_type"); - updateIsaTagSelect("study sample", "#new-attribute-row_sample_collection_sample_type"); - updateIsaTagSelect("assay - material", "#new-attribute-row_sample_type"); - updateIsaTagSelect("assay - data file", "#new-attribute-row_sample_type"); + updateIsaTagSelect("<%= sample_type_level %>", ".sample-attribute"); }); $j(document).on('submit', function(){ // Remove the table from the form From eae11a5df788dbeae2c204977b86e17e0f12b1dc Mon Sep 17 00:00:00 2001 From: Kevin De Pelseneer Date: Fri, 15 Dec 2023 11:03:34 +0100 Subject: [PATCH 07/24] Improve template error messages --- app/models/template.rb | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/app/models/template.rb b/app/models/template.rb index 39dcc0ee6d..ede505d782 100644 --- a/app/models/template.rb +++ b/app/models/template.rb @@ -33,11 +33,17 @@ def resolve_inconsistencies end def validate_template_attributes - errors.add(:base, '[Template attribute]: Some attributes are missing ISA tags') unless none_empty_isa_tag + unless attributes_with_empty_isa_tag.none? + attributes_with_empty_isa_tag.map do |attribute| + errors.add("[#{:template_attributes}]:", "Attribute '#{attribute.title}' is missing an ISA tag") + end + end + if test_tag_occurences.any? test_tag_occurences.map do |tag| - errors.add(:base, - "[Template attribute]: The '#{tag}' ISA tag is not allowed to be used more then once".html_safe) + attributes_with_duplicate_tags = template_attributes.select { |tat| tat.isa_tag&.title == tag }.map(&:title) + errors.add("[#{:template_attributes}]:", + "The '#{tag}' ISA Tag was used in these attributes => #{attributes_with_duplicate_tags.inspect}. This ISA tag is not allowed to be used more then once!") end end @@ -56,8 +62,8 @@ def resolve_controlled_vocabs_inconsistencies end end - def none_empty_isa_tag - template_attributes.select { |ta| !ta.title.include?('Input') && ta.isa_tag_id.nil? }.none? + def attributes_with_empty_isa_tag + template_attributes.select { |ta| !ta.title.include?('Input') && ta.isa_tag_id.nil? } end def test_tag_occurences @@ -74,7 +80,7 @@ def test_input_occurence def test_attribute_title_uniqueness template_attribute_titles = template_attributes.map(&:title).uniq - duplicate_attributes = template_attribute_titles.map do |tat| + template_attribute_titles.map do |tat| if template_attributes.select { |ta| ta.title.downcase == tat.downcase }.map(&:title).count > 1 errors.add(:template_attributes, "Attribute names must be unique, there are duplicates of #{tat}") return tat From a4c840196adaca2830981b6ef8dc8d8ec048f53f Mon Sep 17 00:00:00 2001 From: Kevin De Pelseneer Date: Fri, 15 Dec 2023 11:06:04 +0100 Subject: [PATCH 08/24] filter ISA Tags for all attributes, not only new rows --- app/assets/javascripts/templates.js | 6 +++--- app/views/templates/edit.html.erb | 2 +- app/views/templates/new.html.erb | 5 ++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/templates.js b/app/assets/javascripts/templates.js index fd3c71d7e5..3113e3084d 100644 --- a/app/assets/javascripts/templates.js +++ b/app/assets/javascripts/templates.js @@ -185,14 +185,14 @@ function get_filtered_isa_tags(level) { function updateIsaTagSelect(template_level, attribute_row) { const isa_tags = get_filtered_isa_tags(template_level); - // Remove all options first, except blank one - $j(attribute_row).find('select[data-attr="isa_tag_title"] option:not([value=""])').each(function() { + // Remove all options first from the select items that were not disabled, except blank one + $j(attribute_row).find('select[data-attr="isa_tag_title"]:not(:disabled) option:not([value=""])').each(function() { $j(this).remove(); }); // Append filtered option to a new attribute row $j.each(isa_tags, function (i, tag) { - $j(attribute_row).find('select[data-attr="isa_tag_title"]').append($j('