Skip to content

Commit

Permalink
Merge branch 'main' into issue_1199_add_sharing_permisions_to_sample_…
Browse files Browse the repository at this point in the history
…types
  • Loading branch information
kdp-cloud committed Sep 30, 2024
2 parents 8f6a756 + 8463e27 commit 5f89011
Show file tree
Hide file tree
Showing 116 changed files with 1,766 additions and 409 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ansible-install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
continue-on-error: true
strategy:
matrix:
os: [ubuntu-20.04,ubuntu-22.04]
os: [ubuntu-20.04,ubuntu-22.04,ubuntu-24.04]

services:
mysql:
Expand Down
10 changes: 5 additions & 5 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ GEM
net-smtp (0.4.0.1)
net-protocol
netrc (0.11.0)
nio4r (2.7.0)
nio4r (2.7.3)
nokogiri (1.16.5)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
Expand Down Expand Up @@ -563,7 +563,7 @@ GEM
psych (5.1.0)
stringio
public_suffix (5.0.0)
puma (5.6.8)
puma (5.6.9)
nio4r (~> 2.0)
pyu-ruby-sasl (0.0.3.3)
racc (1.8.0)
Expand Down Expand Up @@ -728,8 +728,8 @@ GEM
netrc (~> 0.8)
reverse_markdown (2.1.1)
nokogiri
rexml (3.2.8)
strscan (>= 3.0.9)
rexml (3.3.6)
strscan
rfc-822 (0.4.1)
rmagick (5.3.0)
pkg-config (~> 1.4)
Expand Down Expand Up @@ -938,7 +938,7 @@ GEM
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.8.1)
webrick (1.8.2)
webrobots (0.1.2)
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
Expand Down
10 changes: 10 additions & 0 deletions app/assets/javascripts/sample_types.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,16 @@ var SampleTypes = {
else {
seek_sample_element.hide();
}
},

expandIRI: function () {
var termIRI = $j(this).next('.term-iri');
termIRI.toggleClass('visible');
}

};


$j(document).ready(function() {
$j('.term-label').on('click', SampleTypes.expandIRI);
});
18 changes: 18 additions & 0 deletions app/assets/stylesheets/linked_extended_metadata.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
.term-label {
font-weight: normal;
text-decoration: underline;
}

.term-iri {
display: none;
background-color: rgba(177, 183, 187, 0.47);
color: black;
font-weight: normal;
}

.term-iri.visible {
display: inline;
opacity: 1;
margin-left: 10px;
}

.linked_extended_metdata .panel-default .panel-heading {
font-weight: bold;
color: #333;
Expand Down
4 changes: 4 additions & 0 deletions app/assets/stylesheets/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,10 @@ div.renderer {
color: if(lightness($text-color) > 50, darken($text-color, 20%), lighten($text-color, 30%));
}

.select2-results__option--highlighted .subtle {
color: unset;
}

span.truncated-name {
display: inline-block;
overflow: hidden;
Expand Down
1 change: 1 addition & 0 deletions app/controllers/admin_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ def update_features_enabled
Seek::Config.documents_enabled = string_to_boolean params[:documents_enabled]
Seek::Config.events_enabled = string_to_boolean params[:events_enabled]
Seek::Config.isa_enabled = string_to_boolean params[:isa_enabled]
Seek::Config.observation_units_enabled = string_to_boolean params[:observation_units_enabled]
Seek::Config.models_enabled = string_to_boolean params[:models_enabled]
Seek::Config.organisms_enabled = string_to_boolean params[:organisms_enabled]
Seek::Config.programmes_enabled = string_to_boolean params[:programmes_enabled]
Expand Down
2 changes: 2 additions & 0 deletions app/controllers/extended_metadata_types_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ class ExtendedMetadataTypesController < ApplicationController
before_action :find_requested_item, only: [:administer_update, :show]
include Seek::IndexPager

api_actions :index, :show

# generated for form, to display fields for selected metadata type
def form_fields
id = params[:id]
Expand Down
2 changes: 2 additions & 0 deletions app/controllers/human_diseases_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class HumanDiseasesController < ApplicationController
include Seek::ExternalServiceWrapper
include Seek::IndexPager

api_actions :index, :show, :create, :update, :destroy

def show
respond_to do |format|
format.html
Expand Down
3 changes: 3 additions & 0 deletions app/controllers/observation_units_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ class ObservationUnitsController < ApplicationController
before_action :login_required,:except=>[:show,:index]
before_action :find_assets, only: [:index]

include Seek::Publishing::PublishingCommon
include Seek::IsaGraphExtensions

api_actions :index, :show, :create, :update, :destroy

def show
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/projects_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,8 @@ def submit_fairdata_station
path = params[:datastation_data].path
policy = Policy.new
policy.set_attributes_with_sharing(policy_params)
datadata_inv = Seek::FairDataStation::Reader.instance.parse_graph(path)
@investigation = Seek::FairDataStation::Writer.instance.construct_isa(datadata_inv.first, current_person, [@project], policy)
datadata_inv = Seek::FairDataStation::Reader.new.parse_graph(path)
@investigation = Seek::FairDataStation::Writer.new.construct_isa(datadata_inv.first, current_person, [@project], policy)
@investigation.save!

respond_to do |format|
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/sample_types_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class SampleTypesController < ApplicationController

before_action :find_and_authorize_requested_item, except: %i[index new create]

api_actions :index
api_actions :index, :show, :create, :update, :destroy

# GET /sample_types/1 ,'sample_attributes','linked_sample_attributes'
# GET /sample_types/1.json
Expand Down
72 changes: 54 additions & 18 deletions app/controllers/samples_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class SamplesController < ApplicationController
include Seek::IsaGraphExtensions
include Seek::Publishing::PublishingCommon

api_actions :index, :show, :create, :update, :destroy, :batch_create

def index
# There must be better ways of coding this
if @data_file || @sample_type
Expand Down Expand Up @@ -221,31 +223,45 @@ def typeahead

def query
project_ids = params[:project_ids]&.map(&:to_i)

attribute_filter_value = params[:template_attribute_value]&.downcase
@result = params[:template_id].present? ?
Template.find(params[:template_id]).sample_types.map(&:samples).flatten : []

if params[:template_attribute_id].present? && params[:template_attribute_value].present?
attribute_title = TemplateAttribute.find(params[:template_attribute_id]).title
@result = @result.select { |s| s.get_attribute_value(attribute_title)&.include?(params[:template_attribute_value]) }
if params[:template_attribute_id].present? && attribute_filter_value.present?
template_attribute = TemplateAttribute.find(params[:template_attribute_id])
@result = @result.select do |s|
sample_attribute = s.sample_type.sample_attributes.detect { |sa| template_attribute.sample_attributes.include? sa }
sample_attribute_title = sample_attribute&.title
if sample_attribute&.sample_attribute_type&.seek_sample_multi?
attr_value = s.get_attribute_value(sample_attribute_title)
attr_value&.any? { |v| v[:title].downcase.include?(attribute_filter_value) }
elsif sample_attribute&.sample_attribute_type&.seek_sample?
s.get_attribute_value(sample_attribute_title)[:title]&.downcase&.include?(attribute_filter_value)
elsif sample_attribute&.sample_attribute_type&.seek_cv_list?
attr_value = s.get_attribute_value(sample_attribute_title)
attr_value&.any? { |v| v.downcase.include?(attribute_filter_value) }
else
s.get_attribute_value(sample_attribute_title)&.downcase&.include?(attribute_filter_value)
end
end
end

if params[:input_template_id].present? # linked
title =
TemplateAttribute.find(params[:input_attribute_id]).title if params[:input_attribute_id].present?
@result = find_samples(@result, :linked_samples,
{ attribute_id: params[:input_attribute_id],
input_template_attribute =
TemplateAttribute.find(params[:input_attribute_id])
@result = filter_linked_samples(@result, :linked_samples,
{ attribute_id: params[:input_attribute_id],
attribute_value: params[:input_attribute_value],
template_id: params[:input_template_id] }, title)
template_id: params[:input_template_id] }, input_template_attribute)
end

if params[:output_template_id].present? # linking
title =
TemplateAttribute.find(params[:output_attribute_id]).title if params[:output_attribute_id].present?
@result = find_samples(@result, :linking_samples,
{ attribute_id: params[:output_attribute_id],
output_template_attribute =
TemplateAttribute.find(params[:output_attribute_id])
@result = filter_linked_samples(@result, :linking_samples,
{ attribute_id: params[:output_attribute_id],
attribute_value: params[:output_attribute_value],
template_id: params[:output_template_id] }, title)
template_id: params[:output_template_id] }, output_template_attribute)
end

@result = @result.select { |s| (project_ids & s.project_ids).any? } if project_ids.present?
Expand Down Expand Up @@ -319,16 +335,36 @@ def find_index_assets
end
end

def find_samples(samples, link, options, title)
# Filters linked samples based on the provided options and template attribute title.
#
# @param samples [Array<Sample>] the list of samples to filter
# @param link [Symbol] the method to call on each sample to get the linked samples (:linked_samples or :linking_samples)
# @param options [Hash] the options for filtering
# @option options [Integer] :template_id the ID of the template to filter by
# @option options [String] :attribute_value the value of the attribute to filter by
# @option options [Integer] :attribute_id the ID of the attribute to filter by
# @param template_attribute_title [String] the title of the template attribute to filter by
# @return [Array<Sample>] the filtered list of samples
def filter_linked_samples(samples, link, options, template_attribute)
raise ArgumentError, "Invalid linking method provided. '#{link.to_s}' is not allowed!" unless %i[linked_samples linking_samples].include? link

template_attribute_title = template_attribute&.title
samples.select do |s|
s.send(link).any? do |x|
selected = x.sample_type.template_id == options[:template_id].to_i
selected = x.get_attribute_value(title)&.include?(options[:attribute_value]) if title.present? && selected
selected || find_samples([x], link, options, title).present?
if template_attribute.sample_attribute_type.seek_sample_multi?
selected = x.get_attribute_value(template_attribute_title)&.any? { |v| v[:title].downcase.include?(options[:attribute_value]) } if template_attribute.present? && selected
elsif template_attribute.sample_attribute_type.seek_sample?
selected = x.get_attribute_value(template_attribute_title)&[:title].downcase&.include?(options[:attribute_value]) if template_attribute.present? && selected
elsif template_attribute.sample_attribute_type.seek_cv_list?
selected = x.get_attribute_value(template_attribute_title)&.any? { |v| v.downcase.include?(options[:attribute_value]) } if template_attribute.present? && selected
else
selected = x.get_attribute_value(template_attribute_title)&.downcase&.include?(options[:attribute_value]&.downcase) if template_attribute.present? && selected
end
selected || filter_linked_samples([x], link, options, template_attribute).present?
end
end
end

def templates_enabled?
unless Seek::Config.isa_json_compliance_enabled
flash[:error] = 'Not available'
Expand Down
11 changes: 1 addition & 10 deletions app/controllers/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,7 @@ def omniauth_failure
def destroy
logout_user
flash[:notice] = 'You have been logged out.'

begin
if request.env['HTTP_REFERER'].try(:normalize_trailing_slash) == search_url.normalize_trailing_slash
redirect_to :root
else
redirect_back(fallback_location: root_path)
end
rescue RedirectBackError
redirect controller: :homes, action: :index
end
redirect_to :root
end

protected
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/templates_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def populate_template
# post
def template_attributes
template = Template.find(params[:id])
items = template.template_attributes.map { |a| { id: a.id, title: a.title } }
items = template.template_attributes.map { |a| { id: a.id, title: a.title.sanitize } }
respond_to do |format|
format.json { render json: items.to_json }
end
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/workflows_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class WorkflowsController < ApplicationController
include RoCrateHandling
include Legacy::WorkflowSupport

api_actions :index, :show, :create, :update, :destroy, :ro_crate, :ro_crate_metadata, :create_version
api_actions :index, :show, :create, :update, :destroy, :ro_crate, :ro_crate_metadata, :create_version, :submit

rescue_from ROCrate::ReadException do |e|
logger.error("Error whilst attempting to read RO-Crate metadata for Workflow #{@workflow&.id}: #{e.exception.class.name} #{e.message}")
Expand Down
10 changes: 0 additions & 10 deletions app/helpers/assays_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,6 @@ def list_assay_human_diseases(attribute, assay_human_diseases, html_options = {}
result.html_safe
end

# the selection dropdown box for selecting the study for an assay
def assay_study_selection(element_name, current_study)
grouped_options = grouped_options_for_study_selection(current_study)
blank = current_study.blank? ? 'Not specified' : nil
disabled = current_study && !current_study.can_edit?
options = grouped_options_for_select(grouped_options, current_study.try(:id))
select_tag(element_name, options,
class: 'form-control', include_blank: blank, disabled: disabled).html_safe
end

# a lightway way to select a SOP - specifically for the assay creation during data file creation
def assay_sop_selection(element_name, current_sop)
sops = authorised_sops(User.current_user.person.projects)
Expand Down
15 changes: 10 additions & 5 deletions app/helpers/samples_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ def display_attribute_value(value, attribute, options = {})
when Seek::Samples::BaseType::CV
seek_cv_attribute_display(value, attribute)
when Seek::Samples::BaseType::CV_LIST
value.each{|v| seek_cv_attribute_display(v, attribute) }.join(', ')
value.map do |v|
seek_cv_attribute_display(v, attribute)
end.join(', ').html_safe
when Seek::Samples::BaseType::LINKED_EXTENDED_METADATA
linked_extended_metadata_attribute_display(value, attribute)
when Seek::Samples::BaseType::LINKED_EXTENDED_METADATA_MULTI
Expand Down Expand Up @@ -173,12 +175,15 @@ def select_cv_source_ontology(sample_controlled_vocab)
end

def seek_cv_attribute_display(value, attribute)
term = attribute.sample_controlled_vocab.sample_controlled_vocab_terms.where(label:value).last
content = value
term = attribute.sample_controlled_vocab.sample_controlled_vocab_terms.where(label: value).last
if term && term.iri.present?
content << " (#{term.iri}) "
iri_content = term.iri.match?(/^https?:\/\//) ? link_to(term.iri, term.iri, target: '_blank') : term.iri
label_tag = content_tag(:label, term.label, class: 'term-label')
iri_tag = content_tag(:label, iri_content, class: 'term-iri badge')
"#{label_tag}#{iri_tag}".html_safe
else
term.label
end
content
end

def linked_extended_metadata_attribute_display(value, attribute)
Expand Down
10 changes: 10 additions & 0 deletions app/helpers/studies_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,14 @@ def authorised_studies(projects = nil)
def show_batch_miappe_button?
ExtendedMetadataType.where(supported_type: 'Study', title: ExtendedMetadataType::MIAPPE_TITLE, enabled: true).any?
end

# the selection dropdown box for selecting the study for a resource, such as assay or observation unit
def resource_study_selection(element_name, current_study)
grouped_options = grouped_options_for_study_selection(current_study)
blank = current_study.blank? ? 'Not specified' : nil
disabled = current_study && !current_study.can_edit?
options = grouped_options_for_select(grouped_options, current_study.try(:id))
select_tag(element_name, options,
class: 'form-control', include_blank: blank, disabled: disabled).html_safe
end
end
Loading

0 comments on commit 5f89011

Please sign in to comment.