diff --git a/app/assets/javascripts/repositories/index.js b/app/assets/javascripts/repositories/index.js index 7305279ea..f01b1d32d 100644 --- a/app/assets/javascripts/repositories/index.js +++ b/app/assets/javascripts/repositories/index.js @@ -159,8 +159,33 @@ var inputField = $('#repository_name'); var value = inputField.val(); inputField.focus().val('').val(value); + }).on('shown.bs.modal', '#export-repositories-modal', function() { + const firstDescription = $(this).find('.description-p1'); + const teamName = firstDescription.data('team-name'); + const exportButton = $(this).find('#export-repositories-modal-submit'); + const exportURL = exportButton.data('export-url'); + firstDescription.html(I18n.t( + 'repositories.index.modal_export.description_p1_html', + { team_name: teamName, repositories_count: CHECKBOX_SELECTOR.selectedRows.length } + )); + + exportButton.on('click', function() { + $.ajax({ + url: exportURL, + method: 'POST', + data: { repository_ids: CHECKBOX_SELECTOR.selectedRows }, + success: function(data) { + HelperModule.flashAlertMsg(data.message, 'success'); + CHECKBOX_SELECTOR.clearSelection(); + $('#export-repositories-modal').modal('hide'); + }, + error: function(data) { + HelperModule.flashAlertMsg(data.responseJSON.message, 'danger'); + } + }); + }); }); - + $('.create-new-repository').initSubmitModal('#create-repo-modal', 'repository'); if (notTurbolinksPreview()) { initRepositoriesDataTable('#repositoriesList', $('.repositories-index').hasClass('archived')); diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 43040bf55..c1def521a 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -9,13 +9,15 @@ class RepositoriesController < ApplicationController include RepositoriesDatatableHelper include MyModulesHelper - before_action :load_repository, except: %i(index create create_modal sidebar archive restore actions_toolbar) + before_action :load_repository, except: %i(index create create_modal sidebar archive restore actions_toolbar + export_modal export_repositories) before_action :load_repositories, only: %i(index show sidebar) before_action :load_repositories_for_archiving, only: :archive before_action :load_repositories_for_restoring, only: :restore before_action :check_view_all_permissions, only: %i(index sidebar) - before_action :check_view_permissions, except: %i(index create_modal create update destroy parse_sheet import_records - sidebar archive restore actions_toolbar) + before_action :check_view_permissions, except: %i(index create_modal create update destroy parse_sheet + import_records sidebar archive restore actions_toolbar + export_modal export_repositories) before_action :check_manage_permissions, only: %i(rename_modal update) before_action :check_delete_permissions, only: %i(destroy destroy_modal) before_action :check_archive_permissions, only: %i(archive restore) @@ -235,6 +237,23 @@ class RepositoriesController < ApplicationController end end + def export_modal + return unless current_user.has_available_exports? + + respond_to do |format| + format.json do + render json: { + html: render_to_string( + partial: 'export_repositories_modal.html.erb', + locals: { team_name: current_team.name, + export_limit: TeamZipExport.exports_limit, + num_of_requests_left: current_user.exports_left - 1 } + ) + } + end + end + end + def copy @tmp_repository = Repository.new( team: current_team, @@ -384,7 +403,8 @@ class RepositoriesController < ApplicationController def export_repositories repositories = Repository.viewable_by_user(current_user, current_team).where(id: params[:repository_ids]) - if repositories.present? + if repositories.present? && current_user.has_available_exports? + current_user.increase_daily_exports_counter! RepositoriesExportJob.perform_later(repositories.pluck(:id), current_user, current_team) render json: { message: t('zip_export.export_request_success') } else diff --git a/app/services/toolbars/repositories_service.rb b/app/services/toolbars/repositories_service.rb index f9de4d8a3..ea2a3796b 100644 --- a/app/services/toolbars/repositories_service.rb +++ b/app/services/toolbars/repositories_service.rb @@ -23,7 +23,7 @@ module Toolbars if @archived_state [restore_action, delete_action] else - [rename_action, duplicate_action, archive_action, share_action] + [rename_action, duplicate_action, export_action, archive_action, share_action] end.compact end @@ -55,6 +55,19 @@ module Toolbars } end + def export_action + return unless @repositories.all? { |repository| can_read_repository?(repository) } + + { + name: 'export', + label: I18n.t('libraries.index.buttons.export'), + button_id: 'exportRepoBtn', + icon: 'sn-icon sn-icon-export', + path: export_modal_team_repositories_path(@current_team), + type: 'remote-modal' + } + end + def archive_action return unless @repositories.all? { |repository| can_archive_repository?(repository) } diff --git a/app/views/repositories/_export_repositories_modal.html.erb b/app/views/repositories/_export_repositories_modal.html.erb new file mode 100644 index 000000000..88832ce90 --- /dev/null +++ b/app/views/repositories/_export_repositories_modal.html.erb @@ -0,0 +1,35 @@ + diff --git a/config/locales/en.yml b/config/locales/en.yml index 117555969..2b0b95cd0 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1711,7 +1711,6 @@ en: no_archived_inventories: "No archived inventories here" no_archived_inventories_matched: "No archived inventories matched your search request" snapshot_provisioning_in_progress: 'Editing is disabled while a snapshot is being created. This will only take a moment.' - options_dropdown: import_items: 'Import' export_items: 'Export' @@ -1738,6 +1737,13 @@ en: description: "Only the structure of the inventory is going to be copied." name_placeholder: "My inventory" copy: "Copy" + modal_export: + title: "Export Inventories" + description_p1_html: "You are about to export %{repositories_count} inventories in %{team_name}'s team." + description_alert: "This process may take minutes to hours, depending on the file size. Any new data entered afterward won't be included in the export." + description_p2: "You will receive an email when the .zip file is ready. A link to your file will also appear in your SciNote notification. For security reasons, this link will expire in 7 days." + description_p3_html: "After you confirm this export, you will have %{remaining_export_requests} export requests left today (max %{requests_limit} requests per day)." + export: "Export" modal_create: title: "Create new inventory" name_label: "Inventory name" @@ -2242,6 +2248,7 @@ en: buttons: edit: "Rename" duplicate: "Duplicate" + export: "Export" archive: "Archive" restore: "Restore" delete: "Delete" diff --git a/config/routes.rb b/config/routes.rb index 5b372f97e..261d9c35d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -197,6 +197,7 @@ Rails.application.routes.draw do get 'create_modal', to: 'repositories#create_modal', defaults: { format: 'json' } get 'actions_toolbar' + get 'export_modal' end get 'destroy_modal', to: 'repositories#destroy_modal', defaults: { format: 'json' }