'
- html.html_safe
- end
-
-end
\ No newline at end of file
diff --git a/app/helpers/extended_metadata_helper.rb b/app/helpers/extended_metadata_helper.rb
new file mode 100644
index 0000000000..e86a5094f0
--- /dev/null
+++ b/app/helpers/extended_metadata_helper.rb
@@ -0,0 +1,45 @@
+module ExtendedMetadataHelper
+ include SamplesHelper
+
+ def extended_metadata_form_field_for_attribute(attribute, resource)
+ element_class = "extended_metadata_attribute_#{attribute.sample_attribute_type.base_type.downcase}"
+ element_name = "#{resource.class.name.underscore}[extended_metadata_attributes][data][#{attribute.title}]"
+
+ if attribute.linked_extended_metadata? || attribute.linked_extended_metadata_multi?
+ content_tag(:span, class: 'linked_extended_metdata') do
+ folding_panel(attribute.label, false, id:attribute.title) do
+ attribute_form_element(attribute, resource.extended_metadata.get_attribute_value(attribute.title), element_name, element_class)
+ end
+ end
+ else
+ content_tag(:label,attribute.label, class: attribute.required? ? 'required' : '') +
+ attribute_form_element(attribute, resource.extended_metadata.get_attribute_value(attribute.title), element_name, element_class)
+ end
+ end
+
+ def extended_metadata_attribute_description(description)
+ html = '
'
+ html += ''+description+''
+ html += '
'
+ html.html_safe
+ end
+
+ def render_extended_metadata_value(attribute, resource)
+
+ if resource.extended_metadata.data[attribute.title].blank?
+ return '' # Return an empty string if the extended metadata is blank.
+ end
+
+ content_tag(:div, class: 'extended_metadata') do
+ if attribute.linked_extended_metadata? || attribute.linked_extended_metadata_multi?
+ content_tag(:span, class: 'linked_extended_metdata_display') do
+ folding_panel(attribute.label, true, id: attribute.title) do
+ display_attribute(resource.extended_metadata, attribute, link: true)
+ end
+ end
+ else
+ label_tag("#{attribute.label} : ") + " " + display_attribute(resource.extended_metadata, attribute, link: true)
+ end
+ end
+ end
+end
diff --git a/app/helpers/policy_helper.rb b/app/helpers/policy_helper.rb
index 1a70d38ff7..7c431caa93 100644
--- a/app/helpers/policy_helper.rb
+++ b/app/helpers/policy_helper.rb
@@ -159,7 +159,7 @@ def project_policy_json(project)
hash.to_json.html_safe
end
- def permission_title(permission, member_prefix: false, icon: false)
+ def permission_title(permission, member_prefix: false, icon: false, link: false)
if permission.is_a?(Permission)
type = permission.contributor_type
contributor = permission.contributor
@@ -168,18 +168,31 @@ def permission_title(permission, member_prefix: false, icon: false)
contributor = permission
end
- if type == 'Person'
+ option = { target: :_blank }
+ case type
+ when 'Person'
text = "#{contributor.first_name} #{contributor.last_name}"
- elsif type == 'WorkGroup'
- text = "#{member_prefix ? 'Members of ' : ''}#{contributor.project.title} @ #{contributor.institution.title}"
+ text = link_to(h(text), contributor, option).html_safe if link
+ when 'WorkGroup'
+ institution = contributor.institution
+ project = contributor.project
+ if link
+ text = "#{member_prefix ? 'Members of ' : ''}#{link_to(h(project.title), project, option)} @ #{link_to(h(institution.title), institution, option)}".html_safe
+ else
+ text = "#{member_prefix ? 'Members of ' : ''}#{project.title} @ #{institution.title}"
+ end
else
- text = "#{member_prefix ? 'Members of ' : ''}#{contributor.title}"
+ if link
+ text = "#{member_prefix ? 'Members of ' : ''}#{link_to(h(contributor.title), contributor, option)}".html_safe
+ else
+ text = "#{member_prefix ? 'Members of ' : ''}#{contributor.title}"
+ end
end
if icon
content_tag(:span, class: 'type-icon-wrapper') do
image_tag(asset_path(icon_filename_for_key(type.underscore)), class: 'type-icon')
- end.html_safe + " #{text}"
+ end.html_safe + " #{text}".html_safe
else
text
end
diff --git a/app/helpers/sample_types_helper.rb b/app/helpers/sample_types_helper.rb
index acc6935501..f2806d453f 100644
--- a/app/helpers/sample_types_helper.rb
+++ b/app/helpers/sample_types_helper.rb
@@ -91,7 +91,7 @@ def sample_attribute_pid_help_icon
private
def displayed_sample_attribute_types
- SampleAttributeType.all.select{|x|!x.linked_custom_metadata?}
+ SampleAttributeType.all.reject{ |x|x.linked_extended_metadata? || x.linked_extended_metadata_multi? }
end
def attribute_type_link(sample_type_attribute)
diff --git a/app/helpers/samples_helper.rb b/app/helpers/samples_helper.rb
index 873898de09..5102b13263 100644
--- a/app/helpers/samples_helper.rb
+++ b/app/helpers/samples_helper.rb
@@ -3,7 +3,7 @@ def sample_form_field_for_attribute(attribute, resource)
element_class = "sample_attribute_#{attribute.sample_attribute_type.base_type.downcase}"
element_name = "sample[data][#{attribute.title}]"
- attribute_form_element(attribute, resource, element_name, element_class)
+ attribute_form_element(attribute, resource.get_attribute_value(attribute.title), element_name, element_class)
end
def controlled_vocab_form_field(sample_controlled_vocab, element_name, values, limit = 1)
@@ -41,33 +41,31 @@ def controlled_vocab_list_form_field(sample_controlled_vocab, element_name, valu
controlled_vocab_form_field(sample_controlled_vocab, element_name, values, nil)
end
- def linked_custom_metadata_form_field(attribute,resource,element_name, element_class,depth)
- linked_cms = resource.linked_custom_metadatas.select{|cm|cm.custom_metadata_attribute==attribute}
-
- id = linked_cms.blank? ? nil : linked_cms.select{|cm| cm.custom_metadata_type.id == attribute.linked_custom_metadata_type.id}.first.id
+ def linked_extended_metadata_multi_form_field(attribute, value, element_name, element_class)
+ render partial: 'extended_metadata/fancy_linked_extended_metadata_multi_attribute_fields',
+ locals: { value: value, attribute: attribute, element_name: element_name, element_class: element_class, collapsed: false }
+ end
+ def linked_extended_metadata_form_field(attribute, value, element_name, element_class,depth)
html = ''
- html += hidden_field_tag "#{element_name}[id]",id
- html += hidden_field_tag "#{element_name}[custom_metadata_type_id]", attribute.linked_custom_metadata_type.id
- html += hidden_field_tag "#{element_name}[custom_metadata_attribute_id]", attribute.id
- attribute.linked_custom_metadata_type.custom_metadata_attributes.each do |attr|
- linked_cm = linked_cms.select{|cm| cm.custom_metadata_type_id == attr.custom_metadata_type_id}.first
- linked_cm ||= CustomMetadata.new(:custom_metadata_type_id => attr.custom_metadata_type_id)
+ Rails.logger.info ActiveSupport::LogSubscriber.new.send(:color, attribute.inspect, :blue, bold = true)
- attr_element_name = "#{element_name}][data][#{attr.title}]"
+ attribute.linked_extended_metadata_type.extended_metadata_attributes.each do |attr|
+ attr_element_name = "#{element_name}[#{attr.title}]"
html += '
'
html += required_span if attr.required?
- if attr.linked_custom_metadata?
- html += '
'
- html += attribute_form_element(attr, linked_cm, attr_element_name, element_class,depth+1)
+ v = value ? value[attr.title] : nil
+ if attr.linked_extended_metadata?
+ html += '
'
+ html += attribute_form_element(attr, v, attr_element_name, element_class,depth+1)
html += '
'
else
- html += attribute_form_element(attr, linked_cm, attr_element_name, element_class)
+ html += attribute_form_element(attr, v, attr_element_name, element_class)
end
unless attr.description.nil?
- html += custom_metadata_attribute_description(attr.description)
+ html += extended_metadata_attribute_description(attr.description)
end
html += '
'
end
@@ -118,8 +116,12 @@ def sample_attribute_display_title(attribute)
title.html_safe
end
- def display_attribute(sample, attribute, options = {})
- value = sample.get_attribute_value(attribute)
+ def display_attribute(resource, attribute, options = {})
+ value = resource.get_attribute_value(attribute)
+ display_attribute_value(value, attribute, options.merge(resource: resource))
+ end
+
+ def display_attribute_value(value, attribute, options = {})
if value.blank?
text_or_not_specified(value)
else
@@ -140,10 +142,12 @@ def display_attribute(sample, attribute, options = {})
seek_cv_attribute_display(value, attribute)
when Seek::Samples::BaseType::CV_LIST
value.each{|v| seek_cv_attribute_display(v, attribute) }.join(', ')
- when Seek::Samples::BaseType::LINKED_CUSTOM_METADATA
- linked_custom_metadata_attribute_display(value)
+ when Seek::Samples::BaseType::LINKED_EXTENDED_METADATA
+ linked_extended_metadata_attribute_display(value, attribute)
+ when Seek::Samples::BaseType::LINKED_EXTENDED_METADATA_MULTI
+ linked_extended_metadata_multi_attribute_display(value, attribute)
else
- default_attribute_display(attribute, options, sample, value)
+ default_attribute_display(value, attribute, options)
end
end
end
@@ -157,19 +161,36 @@ def seek_cv_attribute_display(value, attribute)
content
end
- def linked_custom_metadata_attribute_display(value)
+ def linked_extended_metadata_attribute_display(value, attribute)
html = ''
html += '
'
- CustomMetadata.find(value.id).custom_metadata_attributes.each do |attr|
- html += '
'
- html += ''+' : '
- html += display_attribute(value,attr)
- html += '
'
+ attribute.linked_extended_metadata_type.extended_metadata_attributes.each do |attr|
+ v = value ? value[attr.title.to_s] : nil
+ html += '
'
+ if attr.linked_extended_metadata? || attr.linked_extended_metadata_multi?
+ html += content_tag(:span, class: 'linked_extended_metdata_display') do
+ folding_panel(attr.label, true, id:attr.title) do
+ display_attribute_value(v, attr)
+ end
+ end
+ else
+ html += ''+' : '
+ html += display_attribute_value(v, attr)
end
+ html += '
'
+ end
html += '
'
html.html_safe
end
+ def linked_extended_metadata_multi_attribute_display(values, attribute)
+ html = ''
+ values.each do |value|
+ html += linked_extended_metadata_attribute_display(value, attribute)
+ end
+ html.html_safe
+ end
+
def seek_sample_attribute_display(value)
if value.kind_of?(Array)
value.map {|v| seek_resource_attribute_display(Sample,v)} .join(", ").html_safe
@@ -195,14 +216,14 @@ def seek_resource_attribute_display(clz, value)
end
end
- def default_attribute_display(attribute, options, sample, value)
- resolution = attribute.resolve (value)
- if (resolution != nil)
+ def default_attribute_display(value, attribute, options)
+ resolution = attribute.resolve(value)
+ if resolution
link_to(value, resolution, target: :_blank)
- else if options[:link] && attribute.is_title
- link_to(value, sample)
+ else
+ if options[:link] && options[:resource] && attribute.is_title
+ link_to(value, options[:resource])
else
-
text_or_not_specified(value, auto_link: options[:link])
end
end
@@ -282,8 +303,7 @@ def show_sample_extraction_status?(data_file)
private
- def attribute_form_element(attribute, resource, element_name, element_class, depth=1)
- value = resource.get_attribute_value(attribute.title)
+ def attribute_form_element(attribute, value, element_name, element_class, depth=1)
placeholder = "e.g. #{attribute.sample_attribute_type.placeholder}" unless attribute.sample_attribute_type.placeholder.blank?
case attribute.sample_attribute_type.base_type
@@ -327,8 +347,10 @@ def attribute_form_element(attribute, resource, element_name, element_class, dep
sample_form_field attribute, element_name, value
when Seek::Samples::BaseType::SEEK_SAMPLE_MULTI
sample_multi_form_field attribute, element_name, value
- when Seek::Samples::BaseType::LINKED_CUSTOM_METADATA
- linked_custom_metadata_form_field attribute, resource, element_name, element_class,depth
+ when Seek::Samples::BaseType::LINKED_EXTENDED_METADATA
+ linked_extended_metadata_form_field attribute, value, element_name, element_class,depth
+ when Seek::Samples::BaseType::LINKED_EXTENDED_METADATA_MULTI
+ linked_extended_metadata_multi_form_field attribute, value, element_name, element_class
else
text_field_tag element_name, value, class: "form-control #{element_class}", placeholder: placeholder
end
diff --git a/app/helpers/sharing_permissions_helper.rb b/app/helpers/sharing_permissions_helper.rb
deleted file mode 100644
index 63389141bb..0000000000
--- a/app/helpers/sharing_permissions_helper.rb
+++ /dev/null
@@ -1,225 +0,0 @@
-module SharingPermissionsHelper
-
- ITEMS_NOT_IN_ISA_HASH = {
- "id": "not_isa-tree",
- "data": {
- "loadable": false
- },
- "li_attr": {
- class:"root-node"
- },
- "a_attr": {
-
- },
- "children": [
- ],
- "text": "Not in ISA",
- "state": {
- "opened": true
- }
- }
-
- ALL_INVESTIGATIONS_HASH = {
- "id": "isa-tree",
- "data": {
- "loadable": false
- },
- "li_attr": {
- class:"root-node"
- },
- "a_attr": {
-
- },
- "children": [
- ],
- "text": "ISA",
- "state": {
- "opened": true
- }
- }
-
- def build_tree_json(hash, root_item)
-
- objects = hash[:nodes].map(&:object)
- real_edges = hash[:edges].select { |e| objects.include?(e[0]) }
-
- roots = hash[:nodes].select do |n|
- real_edges.none? { |_parent, child| child == n.object }
- end
-
- nodes = roots.map { |root| create_tree_node(hash, root.object, root_item) }.flatten
- nodes.to_json
- end
-
- def create_tree_node(hash, object, root_item = nil)
-
- child_edges = hash[:edges].select do |parent, _child|
- parent == object
- end
-
- node = hash[:nodes].detect { |n| n.object == object }
-
- entry = {
- id: unique_node_id(object),
- data: { loadable: false },
- li_attr: { 'data-node-id' => node_id(object) },
- children: []
- }
-
- entry[:text] = object.title
- entry[:icon] = asset_path(resource_avatar_path(object) || icon_filename_for_key("#{object.class.name.downcase}_avatar"))
-
- filtered_child_edges = child_edges.reject { |c| (c[1].instance_of? Publication) || (c[1].instance_of?(Seek::ObjectAggregation))}
- child_edges_with_permission = filtered_child_edges.select { |c| c[1].can_manage? }
-
- unless child_edges_with_permission.blank?
- entry[:children] += child_edges_with_permission.map { |c| create_tree_node(hash, c[1], root_item) }
- end
-
- if node.child_count > 0
- if node.child_count > child_edges.count
- entry[:children] << {
- id: unique_child_count_id(object),
- parent: entry[:id],
- text: "Show #{node.child_count - child_edges.count} more",
- a_attr: { class: 'child-count-leaf' },
- li_attr: { 'data-node-id' => child_count_id(object) },
- data: { child_count: true }
- }
- end
- entry[:state] = { opened: false }
- else
- entry[:state] = { opened: false }
- end
- entry
- end
-
- def add_permissions_to_tree_json (parent_node)
-
- parent_node.each do |node|
- node["li_attr"][:class] = "asset-node-row"
- node["a_attr"] = {}
- node["a_attr"][:class] = "asset-node"
-
- if !node["children"].nil? && node["children"].size > 0
- add_permissions_to_tree_json (node["children"])
- end
- add_asset_permission_nodes(node)
- end
- parent_node
- end
-
- def add_asset_permission_nodes(parent_node)
- asset_type = parent_node["id"].split("-")[0]
- asset_id = parent_node["id"].split("-")[1].to_i
-
- # get asset instance
- asset = safe_class_lookup(asset_type.camelize).find(asset_id)
- parent_node["text"] = "#{h(asset.title)} #{icon_link_to("", "new_window", asset , options = {target:'blank',class:'asset-icon',:onclick => 'window.open(this.href, "_blank");'})}"
-
- permissions_array = get_permission(asset)
- parent_node["children"] = permissions_array + parent_node["children"]
- parent_node
- end
-
- def asset_node_json(resource_type, resource_items)
-
- parent = {
- id: resource_type+"-not_isa",
- data: { loadable: false },
- li_attr: {class:"asset-type-node"},
- a_attr: {},
- children: [],
- text: resource_type
- }
-
- resource_items.each do |item|
-
- entry_item = {
- id: unique_node_id(item),
- data: { loadable: false },
- li_attr: { 'data-node-id' => node_id(item), class:"asset-node-row"},
- a_attr: {class:"asset-node"},
- children: [] ,
- icon: asset_path(resource_avatar_path(item) || icon_filename_for_key("#{item.class.name.downcase}_avatar")),
- text: "#{h(item.title)} #{icon_link_to("", "new_window", item , options = {target:'blank',class:'asset-icon',:onclick => 'window.open(this.href, "_blank");'})}"
- }
-
- permissions_array = get_permission(item)
- entry_item[:children] = permissions_array
- parent[:children].append(entry_item)
- end
- parent
- end
-
-
- def create_policy_node(item, policy_text,sharing_policy_changed)
-
- entry = {
- id: unique_policy_node_id(item),
- data: { loadable: false },
- li_attr: { 'data-node-id' => "Permission-"+node_id(item), class:"hide_permission" },
- a_attr: { class:"permission-node #{sharing_policy_changed}"},
- children: [],
- text:policy_text
- }
- entry
- end
-
- def get_permission (item)
-
- policy =[]
-
- # policy
- downloadable = item.try(:is_downloadable?)
- policy_text = "#{Policy.get_access_type_wording(item.policy.access_type, downloadable)} by Public"
- sharing_policy_changed = (@batch_sharing_permission_changed && (@items_for_sharing.include? item) && !@policy_params[:access_type].nil?)? "sharing_permission_changed" : ""
-
- policy.append(create_policy_node(item,policy_text,sharing_policy_changed))
-
- #permission
- option = {:onclick => 'window.open(this.href, "_blank");'}
-
- item.policy.permissions.map do |permission|
- case permission.contributor_type
- when Permission::PROJECT
- m = Project.find(permission.contributor_id)
- policy_text ="#{Policy.get_access_type_wording(permission.access_type, downloadable)} by Project #{link_to(h(m.title), m, option)}"
- sharing_policy_changed = @batch_sharing_permission_changed && (@items_for_sharing.include? item) ? PolicyHelper::permission_changed_item_class(permission, @policy_params) : ""
- policy.append(create_policy_node(item,policy_text,sharing_policy_changed))
- when Permission::WORKGROUP
- m = WorkGroup.find(permission.contributor_id)
- institution = Institution.find(m.institution_id)
- project = Project.find(m.project_id)
- policy_text ="#{Policy.get_access_type_wording(permission.access_type, downloadable)} by #{link_to(h(project.title), project,option)} @ #{link_to(h(institution.title), institution,option)}"
- sharing_policy_changed = @batch_sharing_permission_changed && (@items_for_sharing.include? item) ? PolicyHelper::permission_changed_item_class(permission, @policy_params) : ""
- policy.append(create_policy_node(item,policy_text,sharing_policy_changed))
- when Permission::INSTITUTION
- m = Institution.find(permission.contributor_id)
- policy_text ="#{Policy.get_access_type_wording(permission.access_type, downloadable)} by Institution #{link_to(h(m.title), m,option)}"
- sharing_policy_changed = @batch_sharing_permission_changed && (@items_for_sharing.include? item) ? PolicyHelper::permission_changed_item_class(permission, @policy_params) : ""
- policy.append(create_policy_node(item,policy_text,sharing_policy_changed))
- when Permission::PERSON
- m = Person.find(permission.contributor_id)
- policy_text ="#{Policy.get_access_type_wording(permission.access_type, downloadable)} by People #{link_to(h(m.title), m,option)}"
- sharing_policy_changed = @batch_sharing_permission_changed && (@items_for_sharing.include? item) ? PolicyHelper::permission_changed_item_class(permission, @policy_params) : ""
- policy.append(create_policy_node(item,policy_text,sharing_policy_changed))
- when Permission::PROGRAMME
- m = Programme.find(permission.contributor_id)
- policy_text ="#{Policy.get_access_type_wording(permission.access_type, downloadable)} by Programme #{link_to(h(m.title), m,option)}"
- sharing_policy_changed = @batch_sharing_permission_changed && (@items_for_sharing.include? item) ? PolicyHelper::permission_changed_item_class(permission, @policy_params) : ""
- policy.append(create_policy_node(item,policy_text,sharing_policy_changed))
- end
- end
- policy
- end
-
-
- private
-
- def unique_policy_node_id(object)
- "Permission-#{node_id(object)}-#{rand(2**32).to_s(36)}"
- end
-
-
-end
diff --git a/app/helpers/studies_helper.rb b/app/helpers/studies_helper.rb
index be64a73a89..1e95a3b95c 100644
--- a/app/helpers/studies_helper.rb
+++ b/app/helpers/studies_helper.rb
@@ -24,6 +24,6 @@ def authorised_studies(projects = nil)
end
def show_batch_miappe_button?
- CustomMetadataType.where(supported_type: 'Study', title: 'MIAPPE metadata v1.1').any?
+ ExtendedMetadataType.where(supported_type: 'Study', title: 'MIAPPE metadata v1.1').any?
end
end
diff --git a/app/helpers/workflows_helper.rb b/app/helpers/workflows_helper.rb
index ca875639ca..a447ff61e1 100644
--- a/app/helpers/workflows_helper.rb
+++ b/app/helpers/workflows_helper.rb
@@ -49,6 +49,10 @@ def maturity_badge(level)
content_tag(:span, t("maturity_level.#{level}"), class: "maturity-level label #{label_class}")
end
+ def life_monitor_status_page_url(resource, base: Seek::Config.life_monitor_ui_url)
+ URI.join(base, "/workflow;uuid=#{resource.uuid}").to_s
+ end
+
def test_status_badge(resource)
status = resource.test_status
case status
@@ -65,9 +69,8 @@ def test_status_badge(resource)
label_class = 'label-default'
label = t('test_status.not_available')
end
- url = LifeMonitor::Rest::Client.status_page_url(resource)
- link_to(url, class: 'lifemonitor-status btn btn-default', target: '_blank', rel: 'noopener',
- 'data-tooltip' => 'Click to view in LifeMonitor') do
+ link_to(life_monitor_status_page_url(resource), class: 'lifemonitor-status btn btn-default', target: '_blank',
+ rel: 'noopener', 'data-tooltip' => 'Click to view in LifeMonitor') do
image('life_monitor_icon', class: 'icon lifemonitor-logo') +
'Tests ' +
content_tag(:span, label, class: "test-status label #{label_class}")
diff --git a/app/models/application_record.rb b/app/models/application_record.rb
index a89af79011..1cd2df850e 100644
--- a/app/models/application_record.rb
+++ b/app/models/application_record.rb
@@ -15,7 +15,7 @@ class ApplicationRecord < ActiveRecord::Base
include Seek::TitleTrimmer
include Seek::ActsAsAsset
include Seek::ActsAsISA
- include HasCustomMetadata
+ include HasExtendedMetadata
include Seek::Doi::ActsAsDoiMintable
include Seek::Doi::ActsAsDoiParent
include Seek::ResearchObjects::ActsAsSnapshottable
diff --git a/app/models/concerns/has_custom_metadata.rb b/app/models/concerns/has_custom_metadata.rb
deleted file mode 100644
index c618cd5344..0000000000
--- a/app/models/concerns/has_custom_metadata.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-module HasCustomMetadata
- extend ActiveSupport::Concern
-
- included do
- def custom_metadata_attribute_values_for_search
- custom_metadata ? custom_metadata.data.values.reject(&:blank?).uniq : []
- end
- end
-
- class_methods do
- def has_extended_custom_metadata
- has_one :custom_metadata, as: :item, dependent: :destroy
- accepts_nested_attributes_for :custom_metadata
-
- if Seek::Config.solr_enabled
- searchable(auto_index: false) do
- text :custom_metadata_attribute_values do
- custom_metadata_attribute_values_for_search
- end
- text :custom_metadata_type do
- custom_metadata.custom_metadata_type.title if custom_metadata.present?
- end
- end
- end
- end
- end
-end
-
diff --git a/app/models/concerns/has_extended_metadata.rb b/app/models/concerns/has_extended_metadata.rb
new file mode 100644
index 0000000000..c99293ab19
--- /dev/null
+++ b/app/models/concerns/has_extended_metadata.rb
@@ -0,0 +1,28 @@
+module HasExtendedMetadata
+ extend ActiveSupport::Concern
+
+ included do
+ def extended_metadata_attribute_values_for_search
+ extended_metadata ? extended_metadata.data.values.reject(&:blank?).uniq : []
+ end
+ end
+
+ class_methods do
+ def has_extended_metadata
+ has_one :extended_metadata, as: :item, dependent: :destroy, autosave: true
+ accepts_nested_attributes_for :extended_metadata
+
+ if Seek::Config.solr_enabled
+ searchable(auto_index: false) do
+ text :extended_metadata_attribute_values do
+ extended_metadata_attribute_values_for_search
+ end
+ text :extended_metadata_type do
+ extended_metadata.extended_metadata_type.title if extended_metadata.present?
+ end
+ end
+ end
+ end
+ end
+end
+
diff --git a/app/models/custom_metadata.rb b/app/models/custom_metadata.rb
deleted file mode 100644
index 9831795302..0000000000
--- a/app/models/custom_metadata.rb
+++ /dev/null
@@ -1,78 +0,0 @@
-class CustomMetadata < ApplicationRecord
- include Seek::JSONMetadata::Serialization
-
- belongs_to :item, polymorphic: true
- belongs_to :custom_metadata_type, validate: true
- belongs_to :custom_metadata_attribute
-
- has_many :custom_metadata_resource_links, inverse_of: :custom_metadata, dependent: :destroy
- has_many :linked_custom_metadatas, through: :custom_metadata_resource_links, source: :resource, source_type: 'CustomMetadata', dependent: :destroy
- accepts_nested_attributes_for :linked_custom_metadatas
-
- validates_with CustomMetadataValidator
- validates_associated :linked_custom_metadatas
-
- delegate :custom_metadata_attributes, to: :custom_metadata_type
-
-
- after_create :update_linked_custom_metadata_id, if: :has_linked_custom_metadatas?
-
- def update_linked_custom_metadata_id
- linked_custom_metadatas.each do |cm|
- attr_name = cm.custom_metadata_attribute.title
- data.mass_assign(data.to_hash.update({attr_name => cm.id}), pre_process: false)
- update_column(:json_metadata, data.to_json)
- end
- end
-
- def has_linked_custom_metadatas?
- linked_custom_metadatas.any?
- end
-
-
- # for polymorphic behaviour with sample
- alias_method :metadata_type, :custom_metadata_type
-
- def custom_metadata_type=(type)
- super
- @data = Seek::JSONMetadata::Data.new(type)
- update_json_metadata
- type
- end
-
- def attribute_class
- CustomMetadataAttribute
- end
-
- def update_linked_custom_metadata(parameters)
- cmt_id = parameters[:custom_metadata_type_id]
-
- # return no custom metdata is filled
- seek_cm_attrs = CustomMetadataType.find(cmt_id).custom_metadata_attributes.select(&:linked_custom_metadata?)
- return if seek_cm_attrs.blank?
-
- seek_cm_attrs.each do |cma|
- cma_params = parameters[:data][cma.title.to_sym]
- self.set_linked_custom_metadatas(cma, cma_params) unless cma_params.nil?
-
- cma_linked_cmt = cma.linked_custom_metadata_type.attributes_with_linked_custom_metadata_type
-
- unless cma_linked_cmt.blank?
- cm = self.linked_custom_metadatas.select{|cm| cm.custom_metadata_type.id == cma[:linked_custom_metadata_type_id]}.first
- cm.update_linked_custom_metadata(cma_params)
- end
-
- end
- end
-
- def set_linked_custom_metadatas(cma, cm_params)
-
- if self.new_record?
- self.linked_custom_metadatas.build(custom_metadata_type: cma.linked_custom_metadata_type, data: cm_params[:data], custom_metadata_attribute_id: cm_params[:custom_metadata_attribute_id])
- else
- linked_cm = self.linked_custom_metadatas.select{|cm| cm.custom_metadata_type_id.to_s == cm_params[:custom_metadata_type_id]}.select{|cm|cm.custom_metadata_attribute==cma}.first
- linked_cm.update(cm_params.permit!)
- end
- end
-
-end
diff --git a/app/models/custom_metadata_resource_link.rb b/app/models/custom_metadata_resource_link.rb
deleted file mode 100644
index 2d77cb1984..0000000000
--- a/app/models/custom_metadata_resource_link.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-class CustomMetadataResourceLink < ApplicationRecord
- belongs_to :custom_metadata
- belongs_to :resource, polymorphic: true
-end
diff --git a/app/models/custom_metadata_type.rb b/app/models/custom_metadata_type.rb
deleted file mode 100644
index d8cf297946..0000000000
--- a/app/models/custom_metadata_type.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-class CustomMetadataType < ApplicationRecord
- has_many :custom_metadata_attributes, inverse_of: :custom_metadata_type, dependent: :destroy
-
- validates :title, presence: true
- validates :custom_metadata_attributes, presence: true
- validates :supported_type, presence: true
- validate :supported_type_must_be_valid_type
- validate :unique_titles_for_custom_metadata_attributes
-
- alias_method :metadata_attributes, :custom_metadata_attributes
-
- def attribute_by_title(title)
- custom_metadata_attributes.where(title: title).first
- end
-
- def attribute_by_method_name(method_name)
- custom_metadata_attributes.detect { |attr| attr.method_name == method_name }
- end
-
- def attributes_with_linked_custom_metadata_type
- custom_metadata_attributes.reject {|attr| attr.linked_custom_metadata_type.nil?}
- end
-
- def supported_type_must_be_valid_type
- return if supported_type.blank? # already convered by presence validation
- unless Seek::Util.lookup_class(supported_type, raise: false)
- errors.add(:supported_type, 'is not a type that can supported custom metadata')
- end
- end
-
- def unique_titles_for_custom_metadata_attributes
- titles = custom_metadata_attributes.collect(&:title)
- if titles != titles.uniq
- errors.add(:custom_metadata_attributes, 'must have unique titles')
- end
- end
-end
diff --git a/app/models/data_file.rb b/app/models/data_file.rb
index e77a9a6565..d46c400947 100644
--- a/app/models/data_file.rb
+++ b/app/models/data_file.rb
@@ -150,7 +150,7 @@ def extract_samples(sample_type, confirm = false, overwrite = false)
sample.project_ids = project_ids
sample.contributor = contributor
sample.originating_data_file = self
- sample.policy = policy
+ sample.policy = policy.deep_copy
sample.save if sample.valid? && confirm
extracted << sample
diff --git a/app/models/extended_metadata.rb b/app/models/extended_metadata.rb
new file mode 100644
index 0000000000..873b2a3a2e
--- /dev/null
+++ b/app/models/extended_metadata.rb
@@ -0,0 +1,25 @@
+class ExtendedMetadata < ApplicationRecord
+ include Seek::JSONMetadata::Serialization
+
+ belongs_to :item, polymorphic: true
+ belongs_to :extended_metadata_type, validate: true
+ belongs_to :extended_metadata_attribute
+
+ validates_with ExtendedMetadataValidator
+
+ delegate :extended_metadata_attributes, to: :extended_metadata_type
+
+ # for polymorphic behaviour with sample
+ alias_method :metadata_type, :extended_metadata_type
+
+ def extended_metadata_type=(type)
+ super
+ @data = Seek::JSONMetadata::Data.new(type)
+ update_json_metadata
+ type
+ end
+
+ def attribute_class
+ ExtendedMetadataAttribute
+ end
+end
diff --git a/app/models/custom_metadata_attribute.rb b/app/models/extended_metadata_attribute.rb
similarity index 52%
rename from app/models/custom_metadata_attribute.rb
rename to app/models/extended_metadata_attribute.rb
index 5385115637..0bfdd55db1 100644
--- a/app/models/custom_metadata_attribute.rb
+++ b/app/models/extended_metadata_attribute.rb
@@ -1,9 +1,9 @@
-class CustomMetadataAttribute < ApplicationRecord
+class ExtendedMetadataAttribute < ApplicationRecord
include Seek::JSONMetadata::Attribute
- belongs_to :custom_metadata_type
- belongs_to :linked_custom_metadata_type, class_name: 'CustomMetadataType'
- has_many :custom_metadatas
+ belongs_to :extended_metadata_type
+ belongs_to :linked_extended_metadata_type, class_name: 'ExtendedMetadataType'
+ has_many :extended_metadatas
# to behave like a sample attribute, but is never a title
def is_title
diff --git a/app/models/extended_metadata_type.rb b/app/models/extended_metadata_type.rb
new file mode 100644
index 0000000000..5b17a9abe4
--- /dev/null
+++ b/app/models/extended_metadata_type.rb
@@ -0,0 +1,37 @@
+class ExtendedMetadataType < ApplicationRecord
+ has_many :extended_metadata_attributes, inverse_of: :extended_metadata_type, dependent: :destroy
+
+ validates :title, presence: true
+ validates :extended_metadata_attributes, presence: true
+ validates :supported_type, presence: true
+ validate :supported_type_must_be_valid_type
+ validate :unique_titles_for_extended_metadata_attributes
+
+ alias_method :metadata_attributes, :extended_metadata_attributes
+
+ def attribute_by_title(title)
+ extended_metadata_attributes.where(title: title).first
+ end
+
+ def attribute_by_method_name(method_name)
+ extended_metadata_attributes.detect { |attr| attr.method_name == method_name }
+ end
+
+ def attributes_with_linked_extended_metadata_type
+ extended_metadata_attributes.reject {|attr| attr.linked_extended_metadata_type.nil?}
+ end
+
+ def supported_type_must_be_valid_type
+ return if supported_type.blank? # already convered by presence validation
+ unless Seek::Util.lookup_class(supported_type, raise: false)
+ errors.add(:supported_type, 'is not a type that can supported extended metadata')
+ end
+ end
+
+ def unique_titles_for_extended_metadata_attributes
+ titles = extended_metadata_attributes.collect(&:title)
+ if titles != titles.uniq
+ errors.add(:extended_metadata_attributes, 'must have unique titles')
+ end
+ end
+end
diff --git a/app/models/sample.rb b/app/models/sample.rb
index 94ad1db112..38c8bb6dd6 100644
--- a/app/models/sample.rb
+++ b/app/models/sample.rb
@@ -89,22 +89,10 @@ def referenced_samples
referenced_resources.select { |r| r.is_a?(Sample) }
end
- def state_allows_edit?(*args)
- (id.nil? || originating_data_file.nil?) && super
- end
-
def extracted?
!!originating_data_file
end
- def projects
- extracted? ? originating_data_file.projects : super
- end
-
- def project_ids
- extracted? ? originating_data_file.project_ids : super
- end
-
def creators
extracted? ? originating_data_file.creators : super
end
diff --git a/app/models/sample_attribute.rb b/app/models/sample_attribute.rb
index d348a1669c..4c1f6c847a 100644
--- a/app/models/sample_attribute.rb
+++ b/app/models/sample_attribute.rb
@@ -54,6 +54,10 @@ def short_pid
URI.parse(pid).fragment || pid.gsub(/.*\//,'') || pid
end
+ def linked_extended_metadata_type
+ nil
+ end
+
private
def store_accessor_name
diff --git a/app/models/sample_attribute_type.rb b/app/models/sample_attribute_type.rb
index 79cdbdd895..d53e3191f0 100644
--- a/app/models/sample_attribute_type.rb
+++ b/app/models/sample_attribute_type.rb
@@ -4,7 +4,7 @@ class SampleAttributeType < ApplicationRecord
validate :validate_allowed_type, :validate_regular_expression, :validate_resolution
has_many :sample_attributes, inverse_of: :sample_attribute_type
- has_many :custom_metadata_attributes, inverse_of: :sample_attribute_type
+ has_many :extended_metadata_attributes, inverse_of: :sample_attribute_type
before_save :set_defaults_attributes
after_initialize :set_defaults_attributes
@@ -84,8 +84,12 @@ def seek_resource?
base_type_handler.is_a?(Seek::Samples::AttributeTypeHandlers::SeekResourceAttributeTypeHandler)
end
- def linked_custom_metadata?
- base_type == Seek::Samples::BaseType::LINKED_CUSTOM_METADATA
+ def linked_extended_metadata?
+ base_type == Seek::Samples::BaseType::LINKED_EXTENDED_METADATA
+ end
+
+ def linked_extended_metadata_multi?
+ base_type == Seek::Samples::BaseType::LINKED_EXTENDED_METADATA_MULTI
end
def seek_sample?
diff --git a/app/models/sample_controlled_vocab.rb b/app/models/sample_controlled_vocab.rb
index 00e4cb0596..fb9bfdcec1 100644
--- a/app/models/sample_controlled_vocab.rb
+++ b/app/models/sample_controlled_vocab.rb
@@ -6,7 +6,7 @@ class SampleControlledVocab < ApplicationRecord
after_remove: :update_sample_type_templates,
dependent: :destroy
has_many :sample_attributes, inverse_of: :sample_controlled_vocab
- has_many :custom_metadata_attributes, inverse_of: :sample_controlled_vocab
+ has_many :extended_metadata_attributes, inverse_of: :sample_controlled_vocab
has_many :sample_types, through: :sample_attributes
has_many :samples, through: :sample_types
diff --git a/app/models/study_batch_upload.rb b/app/models/study_batch_upload.rb
index 4c8c1cf122..6a85f47c88 100644
--- a/app/models/study_batch_upload.rb
+++ b/app/models/study_batch_upload.rb
@@ -29,7 +29,7 @@ def self.extract_study_data_from_file(studies_file)
def self.extract_studies_from_file(studies_file)
studies = []
parsed_sheet = Seek::Templates::StudiesReader.new(studies_file)
- metadata_type = CustomMetadataType.where(title: 'MIAPPE metadata', supported_type: 'Study').last
+ metadata_type = ExtendedMetadataType.where(title: 'MIAPPE metadata', supported_type: 'Study').last
columns = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
study_start_row_index = 4
parsed_sheet.each_record(3, columns) do |index, data|
@@ -37,8 +37,8 @@ def self.extract_studies_from_file(studies_file)
studies << Study.new(
title: data[1].value,
description: data[2].value,
- custom_metadata: CustomMetadata.new(
- custom_metadata_type: metadata_type,
+ extended_metadata: ExtendedMetadata.new(
+ extended_metadata_type: metadata_type,
data: generate_metadata(data)
)
)
@@ -106,8 +106,8 @@ def self.unzip_batch(file_path, user_uuid)
def self.get_existing_studies(studies)
existing_studies = []
studies.each do |study|
- study_metadata_id = study.custom_metadata.data[:id]
- find_metadata = CustomMetadata.where('json_metadata LIKE ?', "%\"id\":\"#{study_metadata_id}\"%")
+ study_metadata_id = study.extended_metadata.data[:id]
+ find_metadata = ExtendedMetadata.where('json_metadata LIKE ?', "%\"id\":\"#{study_metadata_id}\"%")
next if find_metadata.nil?
find_metadata.each do |metadata|
diff --git a/app/serializers/base_serializer.rb b/app/serializers/base_serializer.rb
index 5083ce6965..cf38c19f80 100644
--- a/app/serializers/base_serializer.rb
+++ b/app/serializers/base_serializer.rb
@@ -121,22 +121,11 @@ def BaseSerializer.permits policy
end
end
- attribute :extended_attributes, if: -> { object.respond_to?(:custom_metadata) && !object.custom_metadata.blank? } do
- { extended_metadata_type_id: object.custom_metadata.custom_metadata_type_id.to_s,
- attribute_map: get_custom_metadata }
+ attribute :extended_attributes, if: -> { object.respond_to?(:extended_metadata) && !object.extended_metadata.blank? } do
+ { extended_metadata_type_id: object.extended_metadata.extended_metadata_type_id.to_s,
+ attribute_map: object.extended_metadata.data.to_hash }
end
- def get_custom_metadata
- data = object.custom_metadata.data.to_hash
- CustomMetadata.find(object.custom_metadata.id).custom_metadata_attributes.each do |attr|
- if attr.linked_custom_metadata?
- data[attr.title] = display_custom_metadata(data,attr)
- end
- end
- data
- end
-
-
def show_policy?
return false unless object.respond_to?('can_manage?')
@@ -155,17 +144,6 @@ def submitter
private
- def display_custom_metadata(data,attribute)
- linked_data = CustomMetadata.find(data[attribute.title]).data.to_hash
- CustomMetadata.find(data[attribute.title]).custom_metadata_attributes.each do |attr|
- if attr.linked_custom_metadata?
- linked_data[attr.title] = display_custom_metadata(linked_data,attr)
- end
- end
-
- linked_data
- end
-
def determine_submitter(object)
return object.owner if object.respond_to?('owner')
result = object.contributor if object.respond_to?('contributor') && !object.is_a?(Permission)
diff --git a/app/serializers/custom_metadata_type_serializer.rb b/app/serializers/extended_metadata_type_serializer.rb
similarity index 67%
rename from app/serializers/custom_metadata_type_serializer.rb
rename to app/serializers/extended_metadata_type_serializer.rb
index db672815b3..36b251edba 100644
--- a/app/serializers/custom_metadata_type_serializer.rb
+++ b/app/serializers/extended_metadata_type_serializer.rb
@@ -1,14 +1,14 @@
-class CustomMetadataTypeSerializer < BaseSerializer
+class ExtendedMetadataTypeSerializer < BaseSerializer
attributes :title, :supported_type
- attribute :custom_metadata_attributes
+ attribute :extended_metadata_attributes
- def custom_metadata_attributes
- object.custom_metadata_attributes.collect do |attribute|
- get_custom_metadata_attribute(attribute)
+ def extended_metadata_attributes
+ object.extended_metadata_attributes.collect do |attribute|
+ get_extended_metadata_attribute(attribute)
end
end
- def get_custom_metadata_attribute(attribute)
+ def get_extended_metadata_attribute(attribute)
{
"id": attribute.id.to_s,
"title": attribute.title,
diff --git a/app/validators/custom_metadata_validator.rb b/app/validators/custom_metadata_validator.rb
deleted file mode 100644
index c73b9cb1d1..0000000000
--- a/app/validators/custom_metadata_validator.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class CustomMetadataValidator < ActiveModel::Validator
-
- def validate(record)
- record.custom_metadata_attributes.each do |attribute|
- val = record.get_attribute_value(attribute)
- if attribute.test_blank?(val)
- record.errors.add(attribute.title, 'is required') if attribute.required?
- else
- unless attribute.validate_value?(val)
- record.errors.add(attribute.title, "is not a valid #{attribute.sample_attribute_type.title}")
- end
- end
- end
- end
-
-end
\ No newline at end of file
diff --git a/app/validators/extended_metadata_validator.rb b/app/validators/extended_metadata_validator.rb
new file mode 100644
index 0000000000..ba110e9d61
--- /dev/null
+++ b/app/validators/extended_metadata_validator.rb
@@ -0,0 +1,33 @@
+class ExtendedMetadataValidator < ActiveModel::Validator
+ def validate(record)
+ record.extended_metadata_attributes.each do |attribute|
+ val = record.get_attribute_value(attribute)
+ validate_attribute(record, attribute, val)
+ end
+ end
+
+ private
+
+ def validate_attribute(record, attribute, value, prefix = '')
+ if attribute.test_blank?(value)
+ record.errors.add("#{prefix}#{attribute.title}", 'is required') if attribute.required?
+ else
+ unless attribute.validate_value?(value)
+ record.errors.add("#{prefix}#{attribute.title}", "is not a valid #{attribute.sample_attribute_type.title}")
+ end
+ end
+
+ if attribute.linked_extended_metadata?
+ attribute.linked_extended_metadata_type.extended_metadata_attributes.each do |attr|
+ validate_attribute(record, attr, value ? value[attr.accessor_name.to_s] : nil, "#{attribute.title}.")
+ end
+ elsif attribute.linked_extended_metadata_multi?
+ linked_attributes = attribute.linked_extended_metadata_type.extended_metadata_attributes
+ value.each_with_index do |val, index|
+ linked_attributes.each do |attr|
+ validate_attribute(record, attr, val ? val[attr.accessor_name.to_s] : nil, "#{attribute.title}.#{index + 1}.")
+ end
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/views/admin/features_enabled.html.erb b/app/views/admin/features_enabled.html.erb
index 63039940a4..f46346c9d5 100644
--- a/app/views/admin/features_enabled.html.erb
+++ b/app/views/admin/features_enabled.html.erb
@@ -193,11 +193,13 @@
<%= admin_text_setting(:life_monitor_url, Seek::Config.life_monitor_url,
- 'LifeMonitor URL', "The URL of a LifeMonitor instance.") %>
+ 'LifeMonitor API URL', "The API URL of a LifeMonitor instance.") %>
<%= admin_text_setting(:life_monitor_client_id, Seek::Config.life_monitor_client_id,
'LifeMonitor OAuth client ID', 'The ID for this application to authenticate users through the LifeMonitor OAuth provider.') %>
<%= admin_text_setting(:life_monitor_client_secret, Seek::Config.life_monitor_client_secret,
'LifeMonitor OAuth client secret', 'The secret token for this application to authenticate users through the LifeMonitor OAuth provider.') %>
+ <%= admin_text_setting(:life_monitor_ui_url, Seek::Config.life_monitor_ui_url,
+ 'LifeMonitor UI URL', "The UI (app) URL of a LifeMonitor instance.") %>
- You can select an item to be published by checking the Publish
- checkbox beside that item.
+ You can select an item to be published by checking the checkbox beside that item.
-
- |
-
-
-<%= form_tag({:action => :check_related_items},:method=>:post) do -%>
+<%= form_tag({action: :check_related_items},method: :post) do -%>
<% if @assets.empty? %>
All your assets are published or you have no assets in <%= Seek::Config.instance_name %>
+<% end -%>
+
+<% unless @waiting_for_publish_items.empty? -%>
+
The following items require approval:
+
+
+ One or more of the items to be published are associated with a <%= t('project') -%>
+ that has chosen to use the protection of the <%= t('asset_gatekeeper').downcase %>.
+ The <%= t('asset_gatekeeper').downcase %> is a person that needs to approve items before they are finally published.
+
+
+ When you click "Confirm" an email will be sent to that person, and they will either approve or reject the publication.
+ Once this has happened, you will be notified back via an email.
+
+
+
+ <% @waiting_for_publish_items.each do |item| %>
+
Approval required from: <%= item.asset_gatekeepers.collect { |m| link_to(m.title, m) }.join(" or ").html_safe -%>
+
+ <% end %>
+
+<% end -%>
+
+<% unless @items_cannot_publish.blank? -%>
+
The following items cannot be published:
+
+
One or more of the items you selected cannot be published.
+
+ It is likely that the item(s) are associated with a <%= t('project') -%>
+ that has chosen to use the protection of the <%= t('asset_gatekeeper').downcase %>,
+ and an existing request is either waiting approval or it has been rejected.
+ Visit the item(s) page to confirm this.
+
+
If you think this is not the case, please contact your system's administrator.
- If you have the required access rights, you can choose to publish it by checking the
- Publish checkbox beside the item.
+ If you have the required access rights, you can choose to publish it by checking the checkbox beside the item.
If you do not have the required access rights to publish, the checkbox is
disabled. Somebody that can publish that item is listed next to it and you should contact them and ask them to publish it for you.
- One or more of the items to be published are associated with a <%= t('project') -%> that has chosen to use the protection of the <%= t('asset_gatekeeper').downcase %>.
-
-
- The <%= t('asset_gatekeeper').downcase %> is a person that needs to approve items before they are finally published.
-
-
- The affected items, and the related <%= t('asset_gatekeeper').downcase %>, are listed below. When you Submit an email will be sent to that person, and they will either approve
- or reject the publication. Once this has happened, you will be notified back via an email.
-
-
-
The following items require approval from one of the <%= t('asset_gatekeeper').downcase.pluralize %>:
-
- <% @waiting_for_publish_items.each do |item| %>
-
Items are grouped to those included and those not included in the ISA (Investigation-Study-Assay) structure.
-
The item list excludes Project, Institution and Publication since these are always publicly visible
-
You can view current permissions of each item by clicking the item's name.
+
You can view the details of current permissions for each item by clicking the item's policy icon (
+ <%= image('world', title: 'Was published', class: 'visibility_icon') %>
+ <%= image('partial_world', title: 'Visible to everyone, but not accessible', class: 'visibility_icon') %>
+ <%= image('manage', title: 'Custom policy', class: 'visibility_icon') %>
+ <%= image('lock', title: 'Private', class: 'visibility_icon') %>
+ ).
+
You can view the managers for each item by clicking the
+
+ icon.
After your confirmation, the newly modified permissions will be highlighted with .
+ <% resource.extended_metadata.extended_metadata_attributes.each do |attribute| %>
+ <%= render_extended_metadata_value(attribute, resource) %>
+ <% end %>
+
+
+ <% else %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/extended_metadata/_extended_metadata_fields.html.erb b/app/views/extended_metadata/_extended_metadata_fields.html.erb
new file mode 100644
index 0000000000..c11d4f762c
--- /dev/null
+++ b/app/views/extended_metadata/_extended_metadata_fields.html.erb
@@ -0,0 +1,8 @@
+<% extended_metadata_type.extended_metadata_attributes.each do |attribute| %>
+
-<%= 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/app/views/people/_buttons.html.erb b/app/views/people/_buttons.html.erb
index 59e0864aa2..bd48f3beff 100644
--- a/app/views/people/_buttons.html.erb
+++ b/app/views/people/_buttons.html.erb
@@ -1,15 +1,15 @@
<% if mine?(@person) -%>
- <% tooltip_text_sharing = "You can change the sharing policy and permissions for your assets in batch. A preview of selected assets will be given before you choose new permissions for them." %>
- <% tooltip_text_publishing = "Publish your owned assets in one click. A preview will be given before publishing" %>
- <%= button_link_to "Batch permission changes", "publish", batch_sharing_permission_preview_person_path(@person), 'data-tooltip' => tooltip(tooltip_text_sharing) -%>
- <%= button_link_to "Publish your assets", "publish", batch_publishing_preview_person_path(@person), 'data-tooltip' => tooltip(tooltip_text_publishing) -%>
+ <% tooltip_text_sharing = "You can change the sharing policy and permissions for your items in batch. A preview of selected items will be given before you choose new permissions for them." %>
+ <% tooltip_text_publishing = "Publish your owned items in one click. A preview will be given before publishing" %>
+ <%= button_link_to "Batch permission changes", "publish", batch_sharing_permission_preview_person_path(@person), 'data-tooltip': tooltip(tooltip_text_sharing) -%>
+ <%= button_link_to "Publish your items", "publish", batch_publishing_preview_person_path(@person), 'data-tooltip': tooltip(tooltip_text_publishing) -%>
<% if @person.is_in_any_gatekept_projects? %>
<%= button_link_to "Assets awaiting approval", "waiting", waiting_approval_assets_person_path(@person),
- 'data-tooltip' => tooltip("The assets you have requested to publish, but are awaiting the #{t('asset_gatekeeper').downcase} approval") -%>
+ 'data-tooltip': tooltip("The assets you have requested to publish, but are awaiting the #{t('asset_gatekeeper').downcase} approval") -%>
<% end %>
<% if @person.is_asset_gatekeeper_of_any_project? %>
<%= button_link_to "Assets you are Gatekeeping", "waiting", requested_approval_assets_person_path(@person),
- 'data-tooltip' => tooltip("The assets people have requested to publish, but are still awaiting your approval") -%>
+ 'data-tooltip': tooltip("The assets people have requested to publish, but are still awaiting your approval") -%>
<% end %>
<% end %>
@@ -20,7 +20,7 @@
<% if mine?(@person) -%>
\ No newline at end of file
diff --git a/app/views/samples/_attribute_values.html.erb b/app/views/samples/_attribute_values.html.erb
index fdbad7feda..a65fc4324f 100644
--- a/app/views/samples/_attribute_values.html.erb
+++ b/app/views/samples/_attribute_values.html.erb
@@ -1,6 +1,6 @@
<% sample.sample_type.sample_attributes.each do |attribute| %>
+<% end %>
diff --git a/app/views/single_pages/_duplicate_samples_panel.html.erb b/app/views/single_pages/_duplicate_samples_panel.html.erb
new file mode 100644
index 0000000000..3e7696e7a5
--- /dev/null
+++ b/app/views/single_pages/_duplicate_samples_panel.html.erb
@@ -0,0 +1,51 @@
+<% unless @possible_duplicates.nil? or @possible_duplicates.compact.none? %>
+ <%= folding_panel("Possible Duplicates #{@possible_duplicates.size}", true, :id => "duplicate-samples-panel", :body_options => {:id => "duplicate-samples-panel-content"},
+ :help_text => "These new samples have been matched to already existing samples.") do %>
+
+
+
+
+ <% for key in @possible_duplicates[0].keys %>
+ <% unless %w[uuid duplicate].include?(key) %>
+
<%= key %>
+ <% end %>
+ <% end %>
+
+ <% for dupl_sample in @possible_duplicates %>
+
' >
+
+ <% dupl_sample.map do |key, val| %>
+ <% val = '' if key =='id' %>
+ <% unless %w[uuid duplicate].include?(key) %>
+ <% if @multiple_input_fields.include?(key)%>
+
+ <% val.each do |sub_sample| %>
+ '><%= sub_sample['title'] %>
+ <% end %>
+
+ <% else %>
+
' ><%= val %>
+ <% end %>
+ <% end %>
+ <% end %>
+
' class="danger">
+ <% dupl_sample['duplicate'].map do |key, val| %>
+ <% unless %w[uuid duplicate].include?(key) %>
+ <% if @multiple_input_fields.include?(key)%>
+
+ <% val.each do |sub_sample| %>
+ '><%= sub_sample['title'] %>
+ <% end %>
+
+ <% else %>
+
<%= val%>
+ <% end %>
+ <% end %>
+ <% end %>
+
+
+ <% end %>
+
+
+ <% end %>
+<% end %>
diff --git a/app/views/single_pages/_general_panel.html.erb b/app/views/single_pages/_general_panel.html.erb
new file mode 100644
index 0000000000..6880ad7eaf
--- /dev/null
+++ b/app/views/single_pages/_general_panel.html.erb
@@ -0,0 +1,29 @@
+<%= folding_panel("General Information", true, :id => "general-information-panel",
+:help_text => "This pane contains an overview of the permissions needed to upload.") do %>
+ <% [@project, @study, @assay]. map do | asset | %>
+ <% next if asset.nil? %>
+ <% 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:
+ <% can_upload = false %>
+ <% errors.append("You must be a member of this project!") %>
+ <% end %>
+ <% else %>
+ <% if asset.can_view?%>
+
<%= current_user.person.name %> can view:
+ <% else %>
+
<%= current_user.person.name %> can view:
+ <% can_upload = false %>
+ <% errors.append("You must have at least viewing permission for the #{asset_name} '#{asset.title}'.") %>
+ <% end %>
+ <% end %>
+
+ <% end %>
+<% end %>
diff --git a/app/views/single_pages/_new_samples_panel.html.erb b/app/views/single_pages/_new_samples_panel.html.erb
new file mode 100644
index 0000000000..cf157efaa2
--- /dev/null
+++ b/app/views/single_pages/_new_samples_panel.html.erb
@@ -0,0 +1,37 @@
+<% 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"},
+ :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' %>
+
<%= key %>
+ <% end %>
+ <% end %>
+
+ <% for new_sample in @new_samples %>
+ <% new_sample_id = UUID.generate %>
+
+
+ <% new_sample.map do |key, val| %>
+ <% val = '' if key =='id' %>
+ <% unless key == 'uuid' %>
+ <% if @multiple_input_fields.include?(key)%>
+
+ <% val.each do |sub_sample| %>
+ '><%= sub_sample['title'] %>
+ <% end %>
+
+ <% else %>
+
<%= val %>
+ <% end %>
+ <% end %>
+ <% end %>
+
+ <% end %>
+
+
+ <% end %>
+<% end %>
diff --git a/app/views/single_pages/_unauthorized_samples_panel.html.erb b/app/views/single_pages/_unauthorized_samples_panel.html.erb
new file mode 100644
index 0000000000..8ad35705d2
--- /dev/null
+++ b/app/views/single_pages/_unauthorized_samples_panel.html.erb
@@ -0,0 +1,40 @@
+<% unless @unauthorized_samples.nil? or @unauthorized_samples.compact.none? %>
+ <% @can_upload = false %>
+ <% errors.append("There are unauthorized samples present in the spreadsheet.") %>
+ <%= folding_panel("Unauthorized Samples", false, :id => "unauthorized-samples-panel", :body_options => {:id => "unauthorized-samples-panel-content"},
+ :help_text => "Sample the current user does not have permission to edit them.") do %>
+
+
+ You don't have permission to edit the samples listed below. Please contact the submitter of these samples or revert the changes in the spreadsheet to its original values.
+
+
+
+
+
+ <% for key in @unauthorized_samples[0].keys %>
+ <% unless key == 'uuid' %>
+
<%= key %>
+ <% end %>
+ <% end %>
+
+ <% for unauthorized_sample in @unauthorized_samples %>
+