mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-11-11 01:44:34 +08:00
361 lines
9.9 KiB
Ruby
361 lines
9.9 KiB
Ruby
class SamplesController < ApplicationController
|
|
include InputSanitizeHelper
|
|
include ActionView::Helpers::TextHelper
|
|
include ApplicationHelper
|
|
|
|
before_action :load_vars, only: [:edit, :update, :destroy, :show]
|
|
before_action :load_vars_nested, only: [:new, :create]
|
|
|
|
before_action :check_edit_permissions, only: :edit
|
|
before_action :check_destroy_permissions, only: :destroy
|
|
|
|
def new
|
|
respond_to do |format|
|
|
format.html
|
|
if can_create_samples(@team)
|
|
groups = @team.sample_groups.map do |g|
|
|
{ id: g.id, name: sanitize_input(g.name), color: g.color }
|
|
end
|
|
types = @team.sample_types.map do |t|
|
|
{ id: t.id, name: sanitize_input(t.name) }
|
|
end
|
|
format.json do
|
|
render json: {
|
|
sample_groups: groups.as_json,
|
|
sample_types: types.as_json
|
|
}
|
|
end
|
|
else
|
|
format.json { render json: {}, status: :unauthorized }
|
|
end
|
|
end
|
|
end
|
|
|
|
def create
|
|
sample = Sample.new(
|
|
user: current_user,
|
|
team: @team
|
|
)
|
|
sample.last_modified_by = current_user
|
|
errors = {
|
|
init_fields: [],
|
|
custom_fields: []
|
|
};
|
|
|
|
respond_to do |format|
|
|
if can_create_samples(@team)
|
|
if params[:sample]
|
|
# Sample name
|
|
if params[:sample][:name]
|
|
sample.name = params[:sample][:name]
|
|
end
|
|
|
|
# Sample type
|
|
if params[:sample][:sample_type_id] != "-1"
|
|
sample_type = SampleType.find_by_id(params[:sample][:sample_type_id])
|
|
|
|
if sample_type
|
|
sample.sample_type_id = params[:sample][:sample_type_id]
|
|
end
|
|
end
|
|
|
|
# Sample group
|
|
if params[:sample][:sample_group_id] != "-1"
|
|
sample_group = SampleGroup.find_by_id(params[:sample][:sample_group_id])
|
|
|
|
if sample_group
|
|
sample.sample_group_id = params[:sample][:sample_group_id]
|
|
end
|
|
end
|
|
end
|
|
|
|
if !sample.save
|
|
errors[:init_fields] = sample.errors.messages
|
|
else
|
|
# Sample was saved, we can add all newly added sample fields
|
|
params[:custom_fields].to_a.each do |id, val|
|
|
scf = SampleCustomField.new(
|
|
custom_field_id: id,
|
|
sample_id: sample.id,
|
|
value: val
|
|
)
|
|
|
|
if !scf.save
|
|
errors[:custom_fields] << {
|
|
"#{id}": scf.errors.messages
|
|
}
|
|
else
|
|
sample_annotation_notification(sample, scf)
|
|
end
|
|
end
|
|
end
|
|
|
|
errors.delete_if { |k, v| v.blank? }
|
|
if errors.empty?
|
|
format.json do
|
|
render json: {
|
|
id: sample.id,
|
|
flash: t(
|
|
'samples.create.success_flash',
|
|
sample: escape_input(sample.name),
|
|
team: escape_input(@team.name)
|
|
)
|
|
},
|
|
status: :ok
|
|
end
|
|
else
|
|
format.json { render json: errors, status: :bad_request }
|
|
end
|
|
else
|
|
format.json { render json: {}, status: :unauthorized }
|
|
end
|
|
end
|
|
end
|
|
|
|
def show
|
|
respond_to do |format|
|
|
format.json do
|
|
render json: {
|
|
html: render_to_string(
|
|
partial: 'info_sample_modal.html.erb'
|
|
)
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
def edit
|
|
json = {
|
|
sample: {
|
|
name: escape_input(@sample.name),
|
|
sample_type: @sample.sample_type.nil? ? "" : @sample.sample_type.id,
|
|
sample_group: @sample.sample_group.nil? ? "" : @sample.sample_group.id,
|
|
custom_fields: {}
|
|
},
|
|
sample_groups: @team.sample_groups.map do |g|
|
|
{ id: g.id, name: sanitize_input(g.name), color: g.color }
|
|
end,
|
|
sample_types: @team.sample_types.map do |t|
|
|
{ id: t.id, name: sanitize_input(t.name) }
|
|
end
|
|
}
|
|
|
|
# Add custom fields ids as key (easier lookup on js side)
|
|
@sample.sample_custom_fields.each do |scf|
|
|
json[:sample][:custom_fields][scf.custom_field_id] = {
|
|
sample_custom_field_id: scf.id,
|
|
value: escape_input(scf.value)
|
|
}
|
|
end
|
|
|
|
respond_to do |format|
|
|
format.html
|
|
format.json {
|
|
render json: json
|
|
}
|
|
end
|
|
end
|
|
|
|
def update
|
|
sample = Sample.find_by_id(params[:sample_id])
|
|
sample.last_modified_by = current_user
|
|
errors = {
|
|
init_fields: [],
|
|
sample_custom_fields: [],
|
|
custom_fields: []
|
|
};
|
|
|
|
respond_to do |format|
|
|
if sample
|
|
if can_edit_sample(sample)
|
|
if params[:sample]
|
|
if params[:sample][:name]
|
|
sample.name = params[:sample][:name]
|
|
end
|
|
|
|
# Check if user selected empty sample type
|
|
if params[:sample][:sample_type_id] == "-1"
|
|
sample.sample_type_id = nil
|
|
elsif params[:sample][:sample_type_id]
|
|
sample_type = SampleType.find_by_id(params[:sample][:sample_type_id])
|
|
|
|
if sample_type
|
|
sample.sample_type_id = params[:sample][:sample_type_id]
|
|
end
|
|
end
|
|
|
|
# Check if user selected empty sample type
|
|
if params[:sample][:sample_group_id] == "-1"
|
|
sample.sample_group_id = nil
|
|
elsif params[:sample][:sample_group_id]
|
|
sample_group = SampleGroup.find_by_id(params[:sample][:sample_group_id])
|
|
|
|
if sample_group
|
|
sample.sample_group_id = params[:sample][:sample_group_id]
|
|
end
|
|
end
|
|
end
|
|
|
|
# Add all newly added sample fields
|
|
params[:custom_fields].to_a.each do |id, val|
|
|
# Check if client is lying (SCF shouldn't exist)
|
|
scf = SampleCustomField.where("custom_field_id = ? AND sample_id = ?", id, sample.id).take
|
|
|
|
if scf
|
|
old_text = scf.value
|
|
# Well, client was naughty, no XMAS for him this year, update
|
|
# existing SCF instead of creating new one
|
|
scf.value = val
|
|
|
|
if !scf.save
|
|
# This client needs some lessons
|
|
errors[:custom_fields] << {
|
|
"#{id}": scf.errors.messages
|
|
}
|
|
else
|
|
sample_annotation_notification(sample, scf, old_text)
|
|
end
|
|
else
|
|
# SCF doesn't exist, create it
|
|
scf = SampleCustomField.new(
|
|
custom_field_id: id,
|
|
sample_id: sample.id,
|
|
value: val
|
|
)
|
|
|
|
if !scf.save
|
|
errors[:custom_fields] << {
|
|
"#{id}": scf.errors.messages
|
|
}
|
|
else
|
|
sample_annotation_notification(sample, scf)
|
|
end
|
|
end
|
|
end
|
|
|
|
scf_to_delete = []
|
|
# Update all existing custom values
|
|
params[:sample_custom_fields].to_a.each do |id, val|
|
|
scf = SampleCustomField.find_by_id(id)
|
|
|
|
if scf
|
|
# SCF exists, but value is empty, add scf to queue to be deleted
|
|
# (if everything is correct)
|
|
if val.empty?
|
|
scf_to_delete << scf
|
|
else
|
|
old_text = scf.value
|
|
# SCF exists, update away
|
|
scf.value = val
|
|
|
|
if !scf.save
|
|
errors[:sample_custom_fields] << {
|
|
"#{id}": scf.errors.messages
|
|
}
|
|
else
|
|
sample_annotation_notification(sample, scf, old_text)
|
|
end
|
|
end
|
|
else
|
|
# SCF doesn't exist, we can't do much but yield error
|
|
errors[:sample_custom_fields] << {
|
|
"#{id}": I18n.t("samples.edit.scf_does_not_exist")
|
|
}
|
|
end
|
|
end
|
|
|
|
if !sample.save
|
|
errors[:init_fields] = sample.errors.messages
|
|
end
|
|
|
|
errors.delete_if { |k, v| v.blank? }
|
|
if errors.empty?
|
|
# Now we can destroy empty scfs
|
|
scf_to_delete.map(&:destroy)
|
|
|
|
format.json do
|
|
render json: {
|
|
id: sample.id,
|
|
flash: t(
|
|
'samples.update.success_flash',
|
|
sample: escape_input(sample.name),
|
|
team: escape_input(@team.name)
|
|
)
|
|
},
|
|
status: :ok
|
|
end
|
|
else
|
|
format.json { render json: errors, status: :bad_request }
|
|
end
|
|
else
|
|
format.json { render json: {}, status: :unauthorized }
|
|
end
|
|
else
|
|
format.json { render json: {}, status: :not_found }
|
|
end
|
|
end
|
|
end
|
|
|
|
def destroy
|
|
end
|
|
|
|
private
|
|
|
|
def load_vars
|
|
@sample = Sample.find_by_id(params[:id])
|
|
@team = current_team
|
|
|
|
unless @sample
|
|
render_404
|
|
end
|
|
end
|
|
|
|
def load_vars_nested
|
|
@team = Team.find_by_id(params[:team_id])
|
|
|
|
unless @team
|
|
render_404
|
|
end
|
|
end
|
|
|
|
def check_create_permissions
|
|
unless can_create_samples(@team)
|
|
render_403
|
|
end
|
|
end
|
|
|
|
def check_edit_permissions
|
|
unless can_edit_sample(@sample)
|
|
render_403
|
|
end
|
|
end
|
|
|
|
def check_destroy_permissions
|
|
unless can_delete_samples(@team)
|
|
render_403
|
|
end
|
|
end
|
|
|
|
def sample_params
|
|
params.require(:sample).permit(
|
|
:name,
|
|
:sample_type_id,
|
|
:sample_group_id
|
|
)
|
|
end
|
|
|
|
def sample_annotation_notification(sample, scf, old_text = nil)
|
|
table_url = params.fetch(:request_url) { :request_url_must_be_present }
|
|
smart_annotation_notification(
|
|
old_text: (old_text if old_text),
|
|
new_text: scf.value,
|
|
title: t('notifications.sample_annotation_title',
|
|
user: current_user.full_name,
|
|
column: scf.custom_field.name,
|
|
sample: sample.name),
|
|
message: t('notifications.sample_annotation_message_html',
|
|
sample: link_to(sample.name, table_url),
|
|
column: link_to(scf.custom_field.name, table_url))
|
|
)
|
|
end
|
|
end
|