Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Batch sample import activities #971

Merged
merged 14 commits into from
Mar 7, 2025
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<%= t("#{@activity[:key]}", user: @activity[:user], name: @activity[:name]) %>
14 changes: 14 additions & 0 deletions app/components/activities/groups/base_activity_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module Activities
module Groups
# Base Component for rendering an activity of type Namespace for Projects
class BaseActivityComponent < Component
include PathHelper

def initialize(activity: nil)
@activity = activity
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<span>
<% if import_samples_action %>
<%= t(
"#{@activity[:key]}",
user: @activity[:user],
href:
link_to(
@activity[:imported_samples_count],
"#",
class: "text-slate-800 dark:text-slate-300 font-medium cursor-not-allowed",
disabled: true,
),
) %>
<% end %>
</span>
12 changes: 12 additions & 0 deletions app/components/activities/groups/sample_activity_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

module Activities
module Groups
# Component for rendering an group sample activity
class SampleActivityComponent < BaseActivityComponent
def import_samples_action
@activity[:action] == 'import_samples'
end
end
end
end
2 changes: 2 additions & 0 deletions app/components/activities/list_item_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
) %>
<% elsif group_link_action %>
<%= render Activities::NamespaceGroupLinkActivityComponent.new(activity: activity) %>
<% elsif sample_action %>
<%= render Activities::Groups::SampleActivityComponent.new(activity: activity) %>
<% else %>
<%= render Activities::GroupActivityComponent.new(activity: activity) %>
<% end %>
Expand Down
2 changes: 1 addition & 1 deletion app/components/activities/list_item_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def sample_clone_action

def sample_action
%w[sample_create sample_update attachment_create attachment_destroy
metadata_update sample_destroy sample_destroy_multiple].include?(@activity[:action])
metadata_update sample_destroy sample_destroy_multiple import_samples].include?(@activity[:action])
end

def sample_transfer_action
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@
class: "text-slate-800 dark:text-slate-300 font-medium cursor-not-allowed",
disabled: true
) %>
<% elsif import_samples_action %>
<%= t(
"#{@activity[:key]}",
user: @activity[:user],
href:
link_to(
@activity[:imported_samples_count],
"#",
class: "text-slate-800 dark:text-slate-300 font-medium cursor-not-allowed",
disabled: true,
),
) %>
<% else %>
<% if sample_exists(@activity[:sample]) %>
<% url =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ def sample_exists(sample)
def samples_tab
@activity[:action] == 'metadata_update' ? 'metadata' : ''
end

def import_samples_action
@activity[:action] == 'import_samples'
end
end
end
end
10 changes: 10 additions & 0 deletions app/models/concerns/track_activity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ def transfer_activity_parameters(params, activity) # rubocop:disable Metrics/Abc
def namespace_project_sample_activity_parameters(params, activity)
params = add_sample_activity_params(params, activity)
params = add_metadata_template_params(params, activity)
params = add_samples_import_params(params, activity)
add_bulk_sample_params(params, activity)
end

Expand All @@ -234,6 +235,14 @@ def add_metadata_template_params(params, activity)
)
end

def add_samples_import_params(params, activity)
return params unless activity.parameters[:action] == 'import_samples'

params.merge(
imported_samples_count: activity.parameters[:imported_samples_count]
)
end

def add_bulk_sample_params(params, activity)
return params unless activity.parameters[:action] == 'sample_destroy_multiple'

Expand All @@ -249,6 +258,7 @@ def format_created_at(created_at)

def additional_group_activity_params(params, activity) # rubocop:disable Metrics/AbcSize
params = add_metadata_template_params(params, activity)
params = add_samples_import_params(params, activity)

if activity.parameters[:action] == 'group_subgroup_destroy'
params.merge!({ removed_group_puid: activity.parameters[:removed_group_puid] })
Expand Down
50 changes: 46 additions & 4 deletions app/services/samples/batch_file_import_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ def initialize(namespace, user = nil, blob_id = nil, params = {})
@project_puid_column = params[:project_puid_column]
@sample_description_column = params[:sample_description_column]
required_headers = [@sample_name_column, @project_puid_column]
@project_samples_count = {}
@project_puid_map = {}
super(namespace, user, blob_id, required_headers, 0, params)
end

Expand Down Expand Up @@ -52,6 +54,9 @@ def perform_file_import # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
response[sample_name] = process_sample_row(sample_name, project, description, metadata)
end
cleanup_files

create_activities unless @project_samples_count.empty?

response
end

Expand Down Expand Up @@ -105,20 +110,21 @@ def process_metadata_row(data)
end

def process_sample_row(name, project, description, metadata)
sample_params = { name:, description: }
sample_params = { name:, description:, include_activity: false }
sample = Samples::CreateService.new(current_user, project, sample_params).execute

if sample.persisted?
Metadata::UpdateService.new(
sample.project, sample, current_user, { 'metadata' => metadata }
sample.project, sample, current_user, { 'metadata' => metadata, include_activity: false }
).execute

increment_sample_count(project)

sample
else
sample.errors.map do |error|
{
path: ['sample', error.attribute.to_s.camelize(:lower)],
message: error.message
path: ['sample', error.attribute.to_s.camelize(:lower)], message: error.message
}
end
end
Expand All @@ -132,5 +138,41 @@ def group_namespace_projects
}
)
end

def create_activities # rubocop:disable Metrics/MethodLength
total_sample_count = 0
@project_samples_count.each do |project_puid, sample_count|
@project_puid_map[project_puid].namespace.create_activity(
key: 'namespaces_project_namespace.import_samples.create',
owner: current_user,
parameters:
{
imported_samples_count: sample_count,
action: 'import_samples'
}
)
total_sample_count += sample_count
end

return unless @namespace.group_namespace? && total_sample_count.positive?

@namespace.create_activity key: 'group.import_samples.create',
owner: current_user,
parameters:
{
imported_samples_count: total_sample_count,
action: 'import_samples'
}
end

def increment_sample_count(project)
project_puid = project.puid
@project_samples_count[project_puid] = if @project_samples_count.key?(project_puid)
@project_samples_count[project_puid] + 1
else
@project_puid_map[project_puid] = project
1
end
end
end
end
15 changes: 8 additions & 7 deletions app/services/samples/create_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,22 @@ class CreateService < BaseService
def initialize(user = nil, project = nil, params = {})
super(user, params)
@project = project
@sample = Sample.new(params.merge(project_id: project&.id))
@include_activity = params.key?(:include_activity) ? params[:include_activity] : true
@sample = Sample.new(params.merge(project_id: project&.id).except(:include_activity))
end

def execute
authorize! @project, to: :create_sample? unless @project.nil?

if sample.save
if sample.save && @include_activity
@project.namespace.create_activity key: 'namespaces_project_namespace.samples.create',
owner: current_user,
parameters:
{
sample_id: sample.id,
sample_puid: sample.puid,
action: 'sample_create'
}
{
sample_id: sample.id,
sample_puid: sample.puid,
action: 'sample_create'
}
end

update_samples_count if @project.parent.type == 'Group'
Expand Down
2 changes: 1 addition & 1 deletion app/services/samples/metadata/update_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def initialize(project, sample, user = nil, params = {})
@metadata = params['metadata']
@analysis_id = params['analysis_id']
@metadata_changes = { added: [], updated: [], deleted: [], not_updated: [], unchanged: [] }
@include_activity = params.key?('include_activity') ? params['include_activity'] : true
@include_activity = params.key?(:include_activity) ? params[:include_activity] : true
end

def execute # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
Expand Down
2 changes: 1 addition & 1 deletion app/services/workflow_executions/completion_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def merge_metadata_onto_samples
params = {
'metadata' => swe.metadata,
'analysis_id' => @workflow_execution.id,
'include_activity' => false
include_activity: false
}
Samples::Metadata::UpdateService.new(
swe.sample.project, swe.sample, current_user, params
Expand Down
4 changes: 4 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ en:
group:
create_html: "%{user} created group"
destroy_html: "%{user} removed group"
import_samples:
create_html: "%{user} imported %{href} samples to projects within this group"
member:
create_html: "%{user} added member %{href} to group"
destroy_html: "%{user} removed member %{href} from group"
Expand Down Expand Up @@ -278,6 +280,8 @@ en:
namespaces_project_namespace:
create_html: "%{user} created project"
destroy_html: "%{user} removed project"
import_samples:
create_html: "%{user} imported %{href} samples to project"
member:
create_html: "%{user} added member %{href} to project"
destroy_html: "%{user} removed member %{href} from project"
Expand Down
4 changes: 4 additions & 0 deletions config/locales/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ fr:
group:
create_html: "%{user} created group"
destroy_html: "%{user} removed group"
import_samples:
create_html: "%{user} imported %{href} samples to projects within this group"
member:
create_html: "%{user} added member %{href} to group"
destroy_html: "%{user} removed member %{href} from group"
Expand Down Expand Up @@ -278,6 +280,8 @@ fr:
namespaces_project_namespace:
create_html: "%{user} created project"
destroy_html: "%{user} removed project"
import_samples:
create_html: "%{user} imported %{href} samples to project"
member:
create_html: "%{user} added member %{href} to project"
destroy_html: "%{user} removed member %{href} from project"
Expand Down
Loading