mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-26 09:42:46 +08:00
Export repository [aj-SCI-1275]
This commit is contained in:
parent
e26337d5ee
commit
ede744849b
8 changed files with 195 additions and 7 deletions
|
@ -1,8 +1,8 @@
|
|||
GIT
|
||||
remote: git://github.com/einzige/sneaky-save.git
|
||||
revision: 03866e838f62a4b13e15784974fcc13e14cd9502
|
||||
remote: https://github.com/einzige/sneaky-save
|
||||
revision: e7c77674abe74d598dfd58db7c680dd85936f207
|
||||
specs:
|
||||
sneaky-save (0.1.1)
|
||||
sneaky-save (0.1.2)
|
||||
activerecord (>= 3.2.0)
|
||||
|
||||
GEM
|
||||
|
|
|
@ -214,6 +214,54 @@ setTimeout(function() {
|
|||
// Enables noSearchHidden plugin
|
||||
$.fn.dataTable.defaults.noSearchHidden = true;
|
||||
|
||||
$('form#form-export').submit(function(e) {
|
||||
var form = this;
|
||||
|
||||
if (currentMode === 'viewMode') {
|
||||
// Remove all hidden fields
|
||||
$('#form-export').find('input[name=row_ids\\[\\]]').remove();
|
||||
$('#form-export').find('input[name=header_ids\\[\\]]').remove();
|
||||
|
||||
// Append samples
|
||||
appendSamplesIdToForm(form);
|
||||
|
||||
// Append visible column information
|
||||
$('table#repository-table thead tr').children('th').each(function(i) {
|
||||
var th = $(this);
|
||||
var val;
|
||||
if ($(th).attr('id') === 'checkbox' || $(th).attr('id') === 'assigned')
|
||||
val = -1
|
||||
else if ($(th).attr('id') === 'row-name')
|
||||
val = -2;
|
||||
else if ($(th).attr('id') === 'added-by')
|
||||
val = -3;
|
||||
else if ($(th).attr('id') === 'added-on')
|
||||
val = -4;
|
||||
else
|
||||
val = th.attr('id');
|
||||
|
||||
if (val)
|
||||
$(form).append(
|
||||
$('<input>')
|
||||
.attr('type', 'hidden')
|
||||
.attr('name', 'header_ids[]')
|
||||
.val(val)
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function appendSamplesIdToForm(form) {
|
||||
$.each(rowsSelected, function(index, rowId) {
|
||||
$(form).append(
|
||||
$('<input>')
|
||||
.attr('type', 'hidden')
|
||||
.attr('name', 'row_ids[]')
|
||||
.val(rowId)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function initRowSelection() {
|
||||
// Handle clicks on checkbox
|
||||
$('.dt-body-center .repository-row-selector').change(function(e) {
|
||||
|
@ -642,6 +690,16 @@ function updateButtons() {
|
|||
$('#editRepositoryRecord').removeClass('disabled');
|
||||
$('#deleteRepositoryRecordsButton').prop('disabled', false);
|
||||
$('#deleteRepositoryRecordsButton').removeClass('disabled');
|
||||
$('#exportRepositoriesButton').removeClass('disabled');
|
||||
$('#exportRepositoriesButton').prop('disabled', false);
|
||||
$('#exportRepositoriesButton').on('click', function() {
|
||||
$('#exportRepositoryModal')
|
||||
.modal('show')
|
||||
});
|
||||
$('#export-repositories').on('click', function() {
|
||||
animateSpinner(null, true);
|
||||
$('#form-export').submit();
|
||||
});
|
||||
$('#assignRepositoryRecords').removeClass('disabled');
|
||||
$('#assignRepositoryRecords').prop('disabled', false);
|
||||
$('#unassignRepositoryRecords').removeClass('disabled');
|
||||
|
@ -651,6 +709,10 @@ function updateButtons() {
|
|||
$('#editRepositoryRecord').addClass('disabled');
|
||||
$('#deleteRepositoryRecordsButton').prop('disabled', true);
|
||||
$('#deleteRepositoryRecordsButton').addClass('disabled');
|
||||
$('#exportRepositoriesButton').addClass('disabled');
|
||||
$('#exportRepositoriesButton').prop('disabled', true);
|
||||
$('#exportRepositoriesButton').off('click');
|
||||
$('#export-repositories').off('click');
|
||||
$('#assignRepositoryRecords').addClass('disabled');
|
||||
$('#assignRepositoryRecords').prop('disabled', true);
|
||||
$('#unassignRepositoryRecords').addClass('disabled');
|
||||
|
@ -660,6 +722,16 @@ function updateButtons() {
|
|||
$('#editRepositoryRecord').addClass('disabled');
|
||||
$('#deleteRepositoryRecordsButton').prop('disabled', false);
|
||||
$('#deleteRepositoryRecordsButton').removeClass('disabled');
|
||||
$('#exportRepositoriesButton').removeClass('disabled');
|
||||
$('#exportRepositoriesButton').prop('disabled', false);
|
||||
$('#exportRepositoriesButton').on('click', function() {
|
||||
$('#exportRepositoryModal')
|
||||
.modal('show')
|
||||
});
|
||||
$('#export-repositories').on('click', function() {
|
||||
animateSpinner(null, true);
|
||||
$('#form-export').submit();
|
||||
});
|
||||
$('#assignRepositoryRecords').removeClass('disabled');
|
||||
$('#assignRepositoryRecords').prop('disabled', false);
|
||||
$('#unassignRepositoryRecords').removeClass('disabled');
|
||||
|
@ -674,6 +746,8 @@ function updateButtons() {
|
|||
$('#addNewColumn').prop('disabled', true);
|
||||
$('#deleteRepositoryRecordsButton').addClass('disabled');
|
||||
$('#deleteRepositoryRecordsButton').prop('disabled', true);
|
||||
$('#exportRepositoriesButton').addClass('disabled');
|
||||
$('#exportRepositoriesButton').off('click');
|
||||
$('#assignRepositoryRecords').addClass('disabled');
|
||||
$('#assignRepositoryRecords').prop('disabled', true);
|
||||
$('#unassignRepositoryRecords').addClass('disabled');
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class RepositoriesController < ApplicationController
|
||||
before_action :load_vars, except: :repository_table_index
|
||||
before_action :load_vars, except: [:repository_table_index, :export_repository]
|
||||
before_action :check_view_all_permissions, only: :index
|
||||
before_action :check_edit_and_destroy_permissions, only:
|
||||
%(destroy destroy_modal rename_modal update)
|
||||
|
@ -7,6 +7,7 @@ class RepositoriesController < ApplicationController
|
|||
%(copy_modal copy)
|
||||
before_action :check_create_permissions, only:
|
||||
%(create_new_modal create)
|
||||
before_action :generate_zip, only: :export_repository
|
||||
|
||||
def index
|
||||
render('repositories/index')
|
||||
|
@ -185,6 +186,15 @@ class RepositoriesController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def export_repository
|
||||
if params[:row_ids] && params[:header_ids]
|
||||
generate_zip
|
||||
else
|
||||
flash[:alert] = t('zip_export.export_error')
|
||||
end
|
||||
redirect_to :back
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_vars
|
||||
|
@ -212,4 +222,68 @@ class RepositoriesController < ApplicationController
|
|||
def repository_params
|
||||
params.require(:repository).permit(:name)
|
||||
end
|
||||
|
||||
def generate_zip
|
||||
zip = ZipExport.create(user: current_user)
|
||||
zip.generate_exportable_zip(
|
||||
current_user,
|
||||
to_csv(RepositoryRow.where(id: params[:row_ids]), params[:header_ids]),
|
||||
:repositories
|
||||
)
|
||||
end
|
||||
|
||||
def to_csv(rows, headers)
|
||||
require 'csv'
|
||||
|
||||
# Parse headers (magic numbers should be refactored - see
|
||||
# sample-datatable.js)
|
||||
header_names = []
|
||||
headers.each do |header|
|
||||
if header == '-1'
|
||||
next
|
||||
elsif header == '-2'
|
||||
header_names << I18n.t('repositories.table.row_name')
|
||||
elsif header == '-3'
|
||||
header_names << I18n.t('repositories.table.added_by')
|
||||
elsif header == '-4'
|
||||
header_names << I18n.t('repositories.table.added_on')
|
||||
else
|
||||
rc = RepositoryColumn.find_by_id(header)
|
||||
if rc
|
||||
header_names << rc.name
|
||||
else
|
||||
header_names << nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
CSV.generate do |csv|
|
||||
csv << header_names
|
||||
rows.each do |row|
|
||||
sample_row = []
|
||||
row_record = RepositoryRow.where(repository_rows: { id: row })
|
||||
headers.each do |header|
|
||||
if header == '-1'
|
||||
next
|
||||
elsif header == '-2'
|
||||
sample_row << row.name
|
||||
elsif header == '-3'
|
||||
sample_row << row.created_by.full_name
|
||||
elsif header == '-4'
|
||||
sample_row << I18n.l(row.created_at, format: :full)
|
||||
else
|
||||
record = row_record.joins(:repository_columns, :repository_cells)
|
||||
.where(repository_columns: { id: header })
|
||||
.take
|
||||
if record
|
||||
sample_row << record.repository_cells.take.value.data
|
||||
else
|
||||
sample_row << nil
|
||||
end
|
||||
end
|
||||
end
|
||||
csv << sample_row
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -102,8 +102,7 @@ class ZipExport < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
# generates zip export file for samples
|
||||
def generate_samples_zip(tmp_dir, data, options = {})
|
||||
def generate_repositories_zip(tmp_dir, data, options = {})
|
||||
file = FileUtils.touch("#{tmp_dir}/export.csv").first
|
||||
File.open(file, 'wb') { |f| f.write(data) }
|
||||
end
|
||||
|
|
21
app/views/repositories/_export_repository_modal.html.erb
Normal file
21
app/views/repositories/_export_repository_modal.html.erb
Normal file
|
@ -0,0 +1,21 @@
|
|||
<div class="modal fade"
|
||||
id="exportRepositoryModal"
|
||||
tabindex="-1"
|
||||
role="dialog"
|
||||
aria-labelledby="modal-export-repository-label">
|
||||
<div class="modal-dialog" 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 'zip_export.modal_label' %></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<%=t('zip_export.repository_html', repository: repository.name) %>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type='button' class='btn btn-primary' data-dismiss='modal' id='export-repositories'> <%=t 'my_modules.repository.export' %> </button>
|
||||
<button type='button' class='btn btn-default' data-dismiss='modal' id='close-modal-export-repositories'><%= t('general.close')%></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,8 +1,16 @@
|
|||
<%= render partial: "repositories/delete_record_modal.html.erb" %>
|
||||
<%= render partial: "repositories/delete_column_modal.html.erb" %>
|
||||
<%= render partial: 'repositories/export_repository_modal.html.erb',
|
||||
locals: { repository: repository } %>
|
||||
|
||||
<div id="alert-container"></div>
|
||||
|
||||
<% if can_view_repository(repository) %>
|
||||
<%= bootstrap_form_tag(url: export_repository_team_path(repository),
|
||||
html: { id: 'form-export', class: 'hidden' }) do |f| %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<div id="repository-toolbar">
|
||||
|
||||
<% if can_create_repository_records(repository) %>
|
||||
|
@ -12,6 +20,13 @@
|
|||
</button>
|
||||
<% end %>
|
||||
|
||||
<% if can_view_repository(repository) %>
|
||||
<a href="#" class="btn btn-default" id="exportRepositoriesButton">
|
||||
<span class="glyphicon glyphicon-cloud-download"></span>
|
||||
<span class="hidden-xs"><%= t("my_modules.repository.export") %></span>
|
||||
</a>
|
||||
<% end %>
|
||||
|
||||
<div id="datatables-buttons" style="display: inline;">
|
||||
<div id="repository-columns-dropdown" class="dropdown">
|
||||
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">
|
||||
|
|
|
@ -612,6 +612,7 @@ en:
|
|||
more_activities: "Load older activities"
|
||||
repository:
|
||||
head_title: "%{project} | %{module} | Custom repository %{repository}"
|
||||
export: 'Export'
|
||||
|
||||
experiments:
|
||||
new:
|
||||
|
@ -1692,12 +1693,15 @@ en:
|
|||
deleted: "(deleted)"
|
||||
|
||||
zip_export:
|
||||
modal_label: 'Export repository'
|
||||
notification_title: 'Your package is ready to be exported!'
|
||||
expired_title: 'The required file was expired!'
|
||||
expired_description: 'The downloadable file expires in 7 days after its creation.'
|
||||
export_error: 'An error occured.'
|
||||
modal_label: 'Export request received'
|
||||
modal_html: "<p>Your export request is being processed.</p><p>When completed we will <strong>send an email to %{email}</strong> inbox with a link to your exported samples. Note that the link will expire in 7 days.</p>"
|
||||
repository_html: '<p>You are about to export selected items in repository %{repository}</p> <br> Repository will be exported in a .csv file format. You will receive <strong>email with a link</strong> where you can download it.'
|
||||
export_error: "Error when creating zip export."
|
||||
|
||||
# This section contains general words that can be used in any parts of
|
||||
# application.
|
||||
tiny_mce:
|
||||
|
|
|
@ -155,6 +155,7 @@ Rails.application.routes.draw do
|
|||
post 'parse_sheet'
|
||||
post 'import_samples'
|
||||
post 'export_samples'
|
||||
post 'export_repository', to: 'repositories#export_repository'
|
||||
# Used for atwho (smart annotations)
|
||||
get 'atwho_users', to: 'at_who#users'
|
||||
get 'atwho_samples', to: 'at_who#samples'
|
||||
|
|
Loading…
Reference in a new issue