mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-09-20 14:45:56 +08:00
added service object
This commit is contained in:
parent
a865253a2e
commit
cee052fc19
|
@ -1,47 +1,53 @@
|
||||||
(function() {
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
function loadRepositoryTab() {
|
||||||
|
var param, pane;
|
||||||
|
$('#repository-tabs a').on("click", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
pane = $(this);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: $(this).attr('data-url'),
|
||||||
|
type: 'GET',
|
||||||
|
dataType: 'json',
|
||||||
|
success: function (data) {
|
||||||
|
var tabBody = $(pane.context.hash).find(".tab-content-body");
|
||||||
|
tabBody.html(data.html);
|
||||||
|
pane.tab('show');
|
||||||
|
},
|
||||||
|
error: function (error) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// on page load
|
||||||
|
if( param = getParam('repository') ){
|
||||||
|
// load selected tab
|
||||||
|
$('a[href="#custom_repo_' + param + '"]').click();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// load first tab content
|
||||||
|
$('#repository-tabs a:first').click();
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean tab content
|
||||||
|
$('a[data-toggle="tab"]').on('hide.bs.tab', function (e) {
|
||||||
|
$(".tab-content-body").html("");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
$('.delete-repo-option').initializeModal('#delete-repo-modal');
|
$('.delete-repo-option').initializeModal('#delete-repo-modal');
|
||||||
$('.rename-repo-option').initializeModal('#rename-repo-modal');
|
$('.rename-repo-option').initializeModal('#rename-repo-modal');
|
||||||
$('.copy-repo-option').initializeModal('#copy-repo-modal');
|
$('.copy-repo-option').initializeModal('#copy-repo-modal');
|
||||||
$('.create-repository').initializeModal('#create-repo-modal');
|
$('.create-repository').initializeModal('#create-repo-modal');
|
||||||
|
|
||||||
loadRepositoryTab();
|
$(document).ready(function() {
|
||||||
|
loadRepositoryTab();
|
||||||
})();
|
|
||||||
|
|
||||||
function loadRepositoryTab() {
|
|
||||||
$('#repository-tabs a').on("click", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var pane = $(this);
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: $(this).attr("data-url"),
|
|
||||||
type: "GET",
|
|
||||||
dataType: "json",
|
|
||||||
success: function (data) {
|
|
||||||
var tabBody = $(pane.context.hash).find(".tab-content-body");
|
|
||||||
tabBody.html(data.html);
|
|
||||||
pane.tab('show');
|
|
||||||
},
|
|
||||||
error: function (error) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// on page load
|
alert('Banana');
|
||||||
if( param = getParam('repository') ){
|
})();
|
||||||
// load selected tab
|
|
||||||
$('a[href="#custom_repo_'+param+'"]').click();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// load first tab content
|
|
||||||
$('#repository-tabs a:first').click();
|
|
||||||
}
|
|
||||||
|
|
||||||
// clean tab content
|
|
||||||
$('a[data-toggle="tab"]').on('hide.bs.tab', function (e) {
|
|
||||||
$(".tab-content-body").html("");
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class RepositoriesController < ApplicationController
|
class RepositoriesController < ApplicationController
|
||||||
before_action :load_vars, except: :repository_table_index
|
before_action :load_vars, except: [:repository_table_index, :parse_sheet]
|
||||||
before_action :check_view_all_permissions, only: :index
|
before_action :check_view_all_permissions, only: :index
|
||||||
before_action :check_edit_and_destroy_permissions, only:
|
before_action :check_edit_and_destroy_permissions, only:
|
||||||
%(destroy destroy_modal rename_modal update)
|
%(destroy destroy_modal rename_modal update)
|
||||||
|
@ -186,13 +186,49 @@ class RepositoriesController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_sheet
|
def parse_sheet
|
||||||
byebug
|
# byebug
|
||||||
# import_repository = ImportRepository.new(file: params, repository: params)
|
render_404 unless params[:team_id].to_i == current_team.id
|
||||||
|
repository = current_team.repositories.find_by_id(params[:id])
|
||||||
|
imported_file = ::ImportRepository.new(file: params[:file],
|
||||||
|
repository: repository,
|
||||||
|
session: session)
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
unless params[:file]
|
||||||
|
repository_response(t("teams.parse_sheet.errors.no_file_selected"))
|
||||||
|
end
|
||||||
|
begin
|
||||||
|
if imported_file.too_large?
|
||||||
|
repository_response(t('general.file.size_exceeded',
|
||||||
|
file_size: Constants::FILE_MAX_SIZE_MB))
|
||||||
|
else
|
||||||
|
flash[:notice] = t('teams.parse_sheet.errors.empty_file')
|
||||||
|
redirect_to back and return if imported_file.empty?
|
||||||
|
@import_data = imported_file.data
|
||||||
|
if imported_file.generated_temp_file?
|
||||||
|
format.json do
|
||||||
|
render json: {
|
||||||
|
html: render_to_string(
|
||||||
|
partial: 'repositories/parse_records_modal.html.erb'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
repository_response(t('teams.parse_sheet.errors.temp_file_failure'))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rescue ArgumentError, CSV::MalformedCSVError
|
||||||
|
repository_response(t('teams.parse_sheet.errors.invalid_file',
|
||||||
|
encoding: ''.encoding))
|
||||||
|
rescue TypeError
|
||||||
|
repository_response(t('teams.parse_sheet.errors.invalid_extension'))
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def import_repository
|
def import_repository
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def load_vars
|
def load_vars
|
||||||
|
@ -220,4 +256,15 @@ class RepositoriesController < ApplicationController
|
||||||
def repository_params
|
def repository_params
|
||||||
params.require(:repository).permit(:name)
|
params.require(:repository).permit(:name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def repository_response(message)
|
||||||
|
format.html do
|
||||||
|
flash[:alert] = message
|
||||||
|
redirect_to :back
|
||||||
|
end
|
||||||
|
format.json do
|
||||||
|
render json: { message: message },
|
||||||
|
status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
class ImportRepository
|
class ImportRepository
|
||||||
|
include ActionView::Helpers::TextHelper
|
||||||
def initialize(options)
|
def initialize(options)
|
||||||
@file = options.fetch(:file)
|
@file = options.fetch(:file)
|
||||||
@repository = options.fetch(:repository)
|
@repository = options.fetch(:repository)
|
||||||
@sheet = @repository.open_spreadsheet(@file )
|
@session = options.fetch(:session)
|
||||||
|
@sheet = @repository.open_spreadsheet(@file)
|
||||||
end
|
end
|
||||||
|
|
||||||
def data
|
def data
|
||||||
|
@ -11,113 +12,38 @@ class ImportRepository
|
||||||
header = @sheet.row(1)
|
header = @sheet.row(1)
|
||||||
rows = []
|
rows = []
|
||||||
rows << Hash[[header, @sheet.row(2)].transpose]
|
rows << Hash[[header, @sheet.row(2)].transpose]
|
||||||
|
|
||||||
# Fill in fields for dropdown
|
# Fill in fields for dropdown
|
||||||
available_fields = @repository.available_repository_fields.map do |name|
|
available_fields = @repository.available_repository_fields.map do |name|
|
||||||
name.truncate(Constants::NAME_TRUNCATION_LENGTH_DROPDOWN)
|
truncate(name.last, length: Constants::NAME_TRUNCATION_LENGTH_DROPDOWN)
|
||||||
end
|
end
|
||||||
{ header: header, rows: rows, available_fields: available_fields }
|
@temp_file = TempFile.new(session_id: @session.id, file: @file)
|
||||||
|
Data.new(header, rows, available_fields, @repository, @temp_file)
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_file_size
|
def too_large?
|
||||||
return unless @file.size > Constants::FILE_MAX_SIZE_MB.megabytes
|
@file.size > Constants::FILE_MAX_SIZE_MB.megabytes
|
||||||
respond_to do |format|
|
|
||||||
error = t('general.file.size_exceeded',
|
|
||||||
file_size: Constants::FILE_MAX_SIZE_MB)
|
|
||||||
|
|
||||||
format.html do
|
|
||||||
flash[:alert] = error
|
|
||||||
redirect_to session.delete(:return_to)
|
|
||||||
end
|
|
||||||
format.json do
|
|
||||||
render json: { message: error },
|
|
||||||
status: :unprocessable_entity
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_spreadsheet_rows(sheet)
|
def empty?
|
||||||
if @sheet.last_row.between?(0, 1)
|
@sheet.last_row.between?(0, 1)
|
||||||
flash[:notice] = t('teams.parse_sheet.errors.empty_file')
|
|
||||||
redirect_to session.delete(:return_to) and return
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_temp_file
|
def generated_temp_file?
|
||||||
# Save file for next step (importing)
|
# Save file for next step (importing)
|
||||||
@temp_file = TempFile.new(
|
@temp_file = TempFile.new(
|
||||||
session_id: session.id,
|
session_id: @session.id,
|
||||||
file: @file
|
file: @file
|
||||||
)
|
)
|
||||||
respond_to do |format|
|
|
||||||
if @temp_file.save
|
if @temp_file.save
|
||||||
@temp_file.destroy_obsolete
|
@temp_file.destroy_obsolete
|
||||||
# format.html
|
return true
|
||||||
format.json do
|
|
||||||
render json: {
|
|
||||||
html: render_to_string({
|
|
||||||
partial: 'samples/parse_samples_modal.html.erb'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
end
|
|
||||||
else
|
|
||||||
error = t('teams.parse_sheet.errors.temp_file_failure')
|
|
||||||
format.html do
|
|
||||||
flash[:alert] = error
|
|
||||||
redirect_to session.delete(:return_to)
|
|
||||||
end
|
|
||||||
format.json do
|
|
||||||
render json: { message: error },
|
|
||||||
status: :unprocessable_entity
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def argument_error_callback
|
|
||||||
error = t('teams.parse_sheet.errors.invalid_file',
|
|
||||||
encoding: ''.encoding)
|
|
||||||
respond_to do |format|
|
|
||||||
format.html do
|
|
||||||
flash[:alert] = error
|
|
||||||
redirect_to session.delete(:return_to)
|
|
||||||
end
|
|
||||||
format.json do
|
|
||||||
render json: { message: error },
|
|
||||||
status: :unprocessable_entity
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def type_error_callback
|
|
||||||
error = t('teams.parse_sheet.errors.invalid_extension')
|
|
||||||
respond_to do |format|
|
|
||||||
format.html do
|
|
||||||
flash[:alert] = error
|
|
||||||
redirect_to session.delete(:return_to)
|
|
||||||
end
|
|
||||||
format.json do
|
|
||||||
render json: {message: error},
|
|
||||||
status: :unprocessable_entity
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def no_file_callback
|
|
||||||
error = t('teams.parse_sheet.errors.no_file_selected')
|
|
||||||
respond_to do |format|
|
|
||||||
format.html do
|
|
||||||
flash[:alert] = error
|
|
||||||
session[:return_to] ||= request.referer
|
|
||||||
redirect_to session.delete(:return_to)
|
|
||||||
end
|
|
||||||
format.json do
|
|
||||||
render json: { message: error },
|
|
||||||
status: :unprocessable_entity
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Data = Struct.new(
|
||||||
|
:header, :rows, :available_fields, :repository, :temp_file
|
||||||
|
)
|
||||||
# def import_repository
|
# def import_repository
|
||||||
# session[:return_to] ||= request.referer
|
# session[:return_to] ||= request.referer
|
||||||
#
|
#
|
||||||
|
@ -345,6 +271,10 @@ class ImportRepository
|
||||||
# flash[:alert] = error
|
# flash[:alert] = error
|
||||||
# redirect_to session.delete(:return_to)
|
# redirect_to session.delete(:return_to)
|
||||||
# }
|
# }
|
||||||
|
# redirect_to session.delete(:return_to)
|
||||||
|
# }
|
||||||
|
# redirect_to session.delete(:return_to)
|
||||||
|
# }
|
||||||
# format.json {
|
# format.json {
|
||||||
# render json: {message: error},
|
# render json: {message: error},
|
||||||
# status: :unprocessable_entity
|
# status: :unprocessable_entity
|
||||||
|
@ -373,5 +303,61 @@ class ImportRepository
|
||||||
# }
|
# }
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
|
# end format.json {
|
||||||
|
# render json: {message: error},
|
||||||
|
# status: :unprocessable_entity
|
||||||
|
# }
|
||||||
|
# rescue TypeError
|
||||||
|
# error = t("teams.parse_sheet.errors.invalid_extension")
|
||||||
|
# format.html {
|
||||||
|
# flash[:alert] = error
|
||||||
|
# redirect_to session.delete(:return_to)
|
||||||
|
# }
|
||||||
|
# format.json {
|
||||||
|
# render json: {message: error},
|
||||||
|
# status: :unprocessable_entity
|
||||||
|
# }
|
||||||
|
# end
|
||||||
|
# else
|
||||||
|
# error = t("teams.parse_sheet.errors.no_file_selected")
|
||||||
|
# format.html {
|
||||||
|
# flash[:alert] = error
|
||||||
|
# session[:return_to] ||= request.referer
|
||||||
|
# redirect_to session.delete(:return_to)
|
||||||
|
# }
|
||||||
|
# format.json {
|
||||||
|
# render json: {message: error},
|
||||||
|
# status: :unprocessable_entity
|
||||||
|
# }
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# end format.json {
|
||||||
|
# render json: {message: error},
|
||||||
|
# status: :unprocessable_entity
|
||||||
|
# }
|
||||||
|
# rescue TypeError
|
||||||
|
# error = t("teams.parse_sheet.errors.invalid_extension")
|
||||||
|
# format.html {
|
||||||
|
# flash[:alert] = error
|
||||||
|
# redirect_to session.delete(:return_to)
|
||||||
|
# }
|
||||||
|
# format.json {
|
||||||
|
# render json: {message: error},
|
||||||
|
# status: :unprocessable_entity
|
||||||
|
# }
|
||||||
|
# end
|
||||||
|
# else
|
||||||
|
# error = t("teams.parse_sheet.errors.no_file_selected")
|
||||||
|
# format.html {
|
||||||
|
# flash[:alert] = error
|
||||||
|
# session[:return_to] ||= request.referer
|
||||||
|
# redirect_to session.delete(:return_to)
|
||||||
|
# }
|
||||||
|
# format.json {
|
||||||
|
# render json: {message: error},
|
||||||
|
# status: :unprocessable_entity
|
||||||
|
# }
|
||||||
|
# end
|
||||||
|
# end
|
||||||
# end
|
# end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
html: {'data-type' => 'json',
|
html: {'data-type' => 'json',
|
||||||
id: 'form-samples-file'},
|
id: 'form-samples-file'},
|
||||||
remote: :true do |f| %>
|
remote: :true do |f| %>
|
||||||
|
<%= f.hidden_field :team_id, value: current_team.id %>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<%= f.file_field :file %>
|
<%= f.file_field :file %>
|
||||||
</div>
|
</div>
|
||||||
|
|
67
app/views/repositories/_parse_records_modal.html.erb
Normal file
67
app/views/repositories/_parse_records_modal.html.erb
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
<div class="modal-dialog modal-lg" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
|
<h4 class="modal-title"><%= t('samples.modal_import.title') %></h4>
|
||||||
|
</div>
|
||||||
|
<%= bootstrap_form_tag(url: import_records_repository_path(@import_data.repository, format: :json),
|
||||||
|
html: {'data-type' => 'json', id: 'form-import'},
|
||||||
|
remote: true) do |f|%>
|
||||||
|
<div class="modal-body">
|
||||||
|
<h4><%= t("teams.parse_sheet.help_text") %></h4>
|
||||||
|
<div style="overflow-x: scroll">
|
||||||
|
<table class="table" style="display: block">
|
||||||
|
<thead>
|
||||||
|
<th style="min-width: 100px">
|
||||||
|
<p><%= t("teams.parse_sheet.scinote_columns_html") %></p>
|
||||||
|
<p style="margin-bottom: 0px"><%= t("teams.parse_sheet.file_columns") %></p>
|
||||||
|
</th>
|
||||||
|
<% @import_data.header.each.with_index do |th, index| %>
|
||||||
|
<th style="min-width: 150px" title="<%= th %>">
|
||||||
|
<%= f.select("mappings[#{index.to_s}]",
|
||||||
|
options_from_collection_for_select(@import_data.available_fields,
|
||||||
|
:first,
|
||||||
|
:last),
|
||||||
|
include_blank: t('teams.parse_sheet.do_not_include_column'),
|
||||||
|
hide_label: true) %>
|
||||||
|
<br />
|
||||||
|
<% if th.length > Constants::NAME_TRUNCATION_LENGTH_DROPDOWN %>
|
||||||
|
<div class="modal-tooltip">
|
||||||
|
<%= truncate(th, length: Constants::NAME_TRUNCATION_LENGTH_DROPDOWN) %>
|
||||||
|
</div>
|
||||||
|
<% else %>
|
||||||
|
<%= th %>
|
||||||
|
<% end %>
|
||||||
|
</th>
|
||||||
|
<% end %>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% @import_data.rows.each do |row| %>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p><%= t('teams.parse_sheet.example_value') %></p>
|
||||||
|
</td>
|
||||||
|
<% row.each do |td| %>
|
||||||
|
<td>
|
||||||
|
<%= td[1] %>
|
||||||
|
</td>
|
||||||
|
<% end %>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<%= hidden_field_tag 'file_id', @import_data.temp_file.id %>
|
||||||
|
|
||||||
|
<div id="import-errors-container">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal"><%= t('general.cancel')%></button>
|
||||||
|
<input type="submit" class="btn btn-primary" value="<%= t('teams.parse_sheet.import_samples') %>"</input>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%= javascript_include_tag('samples/samples_importer') %>
|
Loading…
Reference in a new issue