From 2d09e6fb6f7b191c589513034a866d1e9e375fca Mon Sep 17 00:00:00 2001 From: Jure Grabnar Date: Thu, 11 Oct 2018 22:55:35 +0200 Subject: [PATCH 1/7] Add export project modal Closes [SCI-2645] --- app/assets/javascripts/projects/index.js | 47 +++++++++++++ app/controllers/teams_controller.rb | 67 ++++++++++++++++--- app/models/concerns/variables_model.rb | 22 ++++++ app/models/user.rb | 10 ++- app/services/team_zip_exporter.rb | 19 ------ app/views/projects/export/_error.html.erb | 6 ++ app/views/projects/export/_success.html.erb | 12 ++++ app/views/projects/index.html.erb | 25 +++++++ config/locales/en.yml | 4 ++ config/routes.rb | 1 + .../20180930205254_add_variables_to_users.rb | 19 ++++++ db/schema.rb | 3 +- 12 files changed, 204 insertions(+), 31 deletions(-) create mode 100644 app/models/concerns/variables_model.rb delete mode 100644 app/services/team_zip_exporter.rb create mode 100644 app/views/projects/export/_error.html.erb create mode 100644 app/views/projects/export/_success.html.erb create mode 100644 db/migrate/20180930205254_add_variables_to_users.rb diff --git a/app/assets/javascripts/projects/index.js b/app/assets/javascripts/projects/index.js index 9e1605d9e..c7c76f486 100644 --- a/app/assets/javascripts/projects/index.js +++ b/app/assets/javascripts/projects/index.js @@ -27,6 +27,10 @@ var projectActionsModalBody = null; var projectActionsModalFooter = null; + var exportProjectsModal = null; + var exportProjectsModalHeader = null; + var exportProjectsModalBody = null; + var projectsViewMode = 'cards'; var projectsViewFilter = $('.projects-view-filter.active').data('filter'); var projectsViewFilterChanged = false; @@ -210,6 +214,44 @@ }); } + /** + * Initialize the JS for export projects modal to work. + */ + function initExportProjectsModal() { + $exportProjectsBtn = $('#export-projects-button') + $exportProjectsBtn.click(function() { + + // Load HTML to refresh users list + $.ajax({ + url: $exportProjectsBtn.data('export-projects-url'), + type: 'POST', + dataType: 'json', + data: { + project_ids: selectedProjects + }, + success: function(data) { + // Update modal title + exportProjectsModalHeader.html(data.title); + + // Set modal body + exportProjectsModalBody.html(data.html); + + // Show the modal + exportProjectsModal.modal('show'); + }, + error: function() { + // TODO + } + }); + }); + + // Remove modal content when modal window is closed. + exportProjectsModal.on('hidden.bs.modal', function() { + exportProjectsModalHeader.html(''); + exportProjectsModalBody.html(''); + }); + } + // Initialize reloading manage user modal content after posting new // user. @@ -295,10 +337,15 @@ projectActionsModalBody = projectActionsModal.find('.modal-body'); projectActionsModalFooter = projectActionsModal.find('.modal-footer'); + exportProjectsModal = $('#export-projects-modal'); + exportProjectsModalHeader = exportProjectsModal.find('.modal-title'); + exportProjectsModalBody = exportProjectsModal.find('.modal-body'); + updateSelectedCards(); initNewProjectModal(); initEditProjectModal(); initManageUsersModal(); + initExportProjectsModal(); Comments.initCommentOptions('ul.content-comments', true); Comments.initEditComments('.panel-project .tab-content'); Comments.initDeleteComments('.panel-project .tab-content'); diff --git a/app/controllers/teams_controller.rb b/app/controllers/teams_controller.rb index b3a363189..81427015b 100644 --- a/app/controllers/teams_controller.rb +++ b/app/controllers/teams_controller.rb @@ -1,11 +1,11 @@ class TeamsController < ApplicationController - before_action :load_vars, only: %i(:parse_sheet :import_samples - :export_samples :export_all) + before_action :load_vars, only: %i(parse_sheet import_samples + export_samples export_projects) before_action :check_create_samples_permissions, only: %i(parse_sheet import_samples) before_action :check_view_samples_permission, only: [:export_samples] - before_action :check_export_all_permission, only: [:export_all] + before_action :check_export_projects_permissions, only: [:export_projects] def parse_sheet session[:return_to] ||= request.referer @@ -225,9 +225,36 @@ class TeamsController < ApplicationController redirect_back(fallback_location: root_path) end - def export_all - if export_params[:project_ids] - TeamZipExporter.generate_zip(export_params, @team, current_user) + def export_projects + if export_projects_params[:project_ids] + # Check if user has enough requests for the day + limit = ENV['EXPORT_ALL_LIMIT_24_HOURS'].to_i || 3 + if current_user.export_vars['num_of_export_all_last_24_hours'] >= limit + render json: { + html: render_to_string( + partial: 'projects/export/error.html.erb', + locals: { limit: limit } + ), + title: t('projects.export_projects.modal_title_error') + } + else + current_user.export_vars['num_of_export_all_last_24_hours'] += 1 + current_user.save + + ids = generate_export_projects_zip + curr_num = current_user.export_vars['num_of_export_all_last_24_hours'] + + render json: { + html: render_to_string( + partial: 'projects/export/success.html.erb', + locals: { num_projects: ids.length, + limit: limit, + num_of_requests_left: limit - curr_num } + ), + title: t('projects.export_projects.modal_title_success') + } + end + return else flash[:alert] = t('zip_export.export_error') end @@ -270,6 +297,10 @@ class TeamsController < ApplicationController params.permit(sample_ids: [], header_ids: []).to_h end + def export_projects_params + params.permit(:id, project_ids: []).to_h + end + def check_create_samples_permissions render_403 unless can_create_samples?(@team) end @@ -280,13 +311,13 @@ class TeamsController < ApplicationController end end - def check_export_all_permission + def check_export_projects_permissions render_403 unless can_read_team?(@team) - if export_params[:project_ids] - projects = Project.where(id: export_params[:project_ids]) + if export_projects_params[:project_ids] + projects = Project.where(id: export_projects_params[:project_ids]) projects.each do |project| - render_403 unless can_read_project(current_user, project) + render_403 unless can_read_project?(current_user, project) end end end @@ -302,4 +333,20 @@ class TeamsController < ApplicationController :samples ) end + + def generate_export_projects_zip + ids = Project.where(id: export_projects_params[:project_ids], + team_id: @team) + .index_by(&:id) + + options = { team: @team } + zip = TeamZipExport.create(user: current_user) + zip.generate_exportable_zip( + current_user, + ids, + :teams, + options + ) + ids + end end diff --git a/app/models/concerns/variables_model.rb b/app/models/concerns/variables_model.rb new file mode 100644 index 000000000..637161b8e --- /dev/null +++ b/app/models/concerns/variables_model.rb @@ -0,0 +1,22 @@ +module VariablesModel + extend ActiveSupport::Concern + + @@default_variables = HashWithIndifferentAccess.new + + included do + serialize :variables, JsonbHashSerializer + after_initialize :init_default_variables, if: :new_record? + end + + class_methods do + def default_variables(dfs) + @@default_variables.merge!(dfs) + end + end + + protected + + def init_default_variables + self.variables = @@default_variables + end +end diff --git a/app/models/user.rb b/app/models/user.rb index c124181ca..96cc4dc5e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,5 +1,5 @@ class User < ApplicationRecord - include SearchableModel, SettingsModel + include SearchableModel, SettingsModel, VariablesModel include User::TeamRoles, User::ProjectRoles acts_as_token_authenticatable @@ -47,6 +47,14 @@ class User < ApplicationRecord } ) + store_accessor :variables, :export_vars + + default_variables( + export_vars: { + num_of_export_all_last_24_hours: 0 + } + ) + # Relations has_many :user_identities, inverse_of: :user has_many :user_teams, inverse_of: :user diff --git a/app/services/team_zip_exporter.rb b/app/services/team_zip_exporter.rb deleted file mode 100644 index 009a70727..000000000 --- a/app/services/team_zip_exporter.rb +++ /dev/null @@ -1,19 +0,0 @@ -module TeamZipExporter - def self.generate_zip(params, team, current_user) - Rails.logger.info('Exporting team zip') - - project_ids = params[:project_ids] - ids = Project.where(id: project_ids, - team_id: team) - .index_by(&:id) - - options = { team: team } - zip = TeamZipExport.create(user: current_user) - zip.generate_exportable_zip( - current_user, - ids, - :teams, - options - ) - end -end diff --git a/app/views/projects/export/_error.html.erb b/app/views/projects/export/_error.html.erb new file mode 100644 index 000000000..2f1bd5365 --- /dev/null +++ b/app/views/projects/export/_error.html.erb @@ -0,0 +1,6 @@ +

+ It looks like you have exceeded your daily export limit. The number of exports is limited to <%= limit %> requests per day - you currently have 0 export requests left. +

+ +

Please repeat the desired action tomorrow, when your daily limit will rise back to <%= limit %> export requests. +

diff --git a/app/views/projects/export/_success.html.erb b/app/views/projects/export/_success.html.erb new file mode 100644 index 000000000..12f05de3e --- /dev/null +++ b/app/views/projects/export/_success.html.erb @@ -0,0 +1,12 @@ +

Your export request for <%= num_projects %> projects in <%= @team.name %> team is being processed and will soon be exported in a .zip file format. It may take anywhere from 5 minutes up to several hours, depending on the file size. Please also note, that any new data in the projects from this point will not be included in the exported file. +

+ +

+ When it's ready, you will receive a confirmation e-mail and the link to your file will appear in your SciNote notifications. For security reasons, the link will expire in 7 days. +

+ +

+ + Please note that the number of exports is limited to <%= limit %> requests per day - you currently have <%= num_of_requests_left %> more. + +

diff --git a/app/views/projects/index.html.erb b/app/views/projects/index.html.erb index 402d85ba1..0a57952b4 100644 --- a/app/views/projects/index.html.erb +++ b/app/views/projects/index.html.erb @@ -77,6 +77,23 @@ + + +
@@ -115,6 +132,14 @@
+ + + diff --git a/config/locales/en.yml b/config/locales/en.yml index ddb60478e..fb97387cf 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -283,6 +283,10 @@ en: invite_users_link: "Invite users" invite_users_details: "to team %{team}." contact_admins: "To invite additional users to team %{team}, contact its administrator/s." + export_projects: + export_button: "Export projects..." + modal_title_success: 'Your export is being prepared' + modal_title_error: 'Your export is denied' table: status: "Status" name: "Project name" diff --git a/config/routes.rb b/config/routes.rb index 9cc9295f4..0c70c2a81 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -178,6 +178,7 @@ Rails.application.routes.draw do # post 'import_samples' # post 'export_samples' post 'export_repository', to: 'repositories#export_repository' + post 'export_projects' # Used for atwho (smart annotations) get 'atwho_users', to: 'at_who#users' get 'atwho_repositories', to: 'at_who#repositories' diff --git a/db/migrate/20180930205254_add_variables_to_users.rb b/db/migrate/20180930205254_add_variables_to_users.rb new file mode 100644 index 000000000..9b40123fa --- /dev/null +++ b/db/migrate/20180930205254_add_variables_to_users.rb @@ -0,0 +1,19 @@ +class AddVariablesToUsers < ActiveRecord::Migration[5.1] + def up + add_column :users, :variables, :jsonb, default: {}, null: false + + User.find_each do |user| + variables = { + export_vars: { + num_of_export_all_last_24_hours: 0 + } + } + + user.update(variables: variables) + end + end + + def down + remove_column :users, :variables, :jsonb + end +end diff --git a/db/schema.rb b/db/schema.rb index ce0aa9260..f99bbd8b0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180524091143) do +ActiveRecord::Schema.define(version: 20180930205254) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -786,6 +786,7 @@ ActiveRecord::Schema.define(version: 20180524091143) do t.integer "current_team_id" t.string "authentication_token", limit: 30 t.jsonb "settings", default: {}, null: false + t.jsonb "variables", default: {}, null: false t.index "trim_html_tags((full_name)::text) gin_trgm_ops", name: "index_users_on_full_name", using: :gin t.index ["authentication_token"], name: "index_users_on_authentication_token", unique: true t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true From e636f61d135e97f3c253cbe7f23e115a8f160be1 Mon Sep 17 00:00:00 2001 From: Jure Grabnar Date: Fri, 12 Oct 2018 00:33:23 +0200 Subject: [PATCH 2/7] Add reset_export_projects_counter rake task --- lib/tasks/exportable_items.rake | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/tasks/exportable_items.rake b/lib/tasks/exportable_items.rake index c1775d87e..2f9946b6e 100644 --- a/lib/tasks/exportable_items.rake +++ b/lib/tasks/exportable_items.rake @@ -6,4 +6,22 @@ namespace :exportable_items do puts "All exportable zip files older than " \ "'#{num.days.ago}' have been removed" end + + desc 'Resets export project counter to 0' + task reset_export_projects_counter: :environment do + User.all.each do |user| + User.transaction do + begin + user.export_vars['num_of_export_all_last_24_hours'] = 0 + user.save + rescue ActiveRecord::ActiveRecordError, + ArgumentError, + ActiveRecord::RecordNotSaved => e + puts "Error creating user, transaction reverted: #{e}" + end + end + end + puts 'Export project counter successfully ' \ + 'reset on all users' + end end From 21298415f03a0b803c1181bf6cc079ddcbba3724 Mon Sep 17 00:00:00 2001 From: Jure Grabnar Date: Fri, 12 Oct 2018 00:48:12 +0200 Subject: [PATCH 3/7] Fix formatting according to HoundBot --- app/assets/javascripts/projects/index.js | 42 +++++++++---------- app/models/concerns/variables_model.rb | 2 + app/models/user.rb | 7 +++- .../20180930205254_add_variables_to_users.rb | 2 + 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/app/assets/javascripts/projects/index.js b/app/assets/javascripts/projects/index.js index c7c76f486..9defd81df 100644 --- a/app/assets/javascripts/projects/index.js +++ b/app/assets/javascripts/projects/index.js @@ -219,31 +219,31 @@ */ function initExportProjectsModal() { $exportProjectsBtn = $('#export-projects-button') - $exportProjectsBtn.click(function() { + $exportProjectsBtn.click(function() { - // Load HTML to refresh users list - $.ajax({ - url: $exportProjectsBtn.data('export-projects-url'), - type: 'POST', - dataType: 'json', - data: { - project_ids: selectedProjects - }, - success: function(data) { - // Update modal title - exportProjectsModalHeader.html(data.title); + // Load HTML to refresh users list + $.ajax({ + url: $exportProjectsBtn.data('export-projects-url'), + type: 'POST', + dataType: 'json', + data: { + project_ids: selectedProjects + }, + success: function(data) { + // Update modal title + exportProjectsModalHeader.html(data.title); - // Set modal body - exportProjectsModalBody.html(data.html); + // Set modal body + exportProjectsModalBody.html(data.html); - // Show the modal - exportProjectsModal.modal('show'); - }, - error: function() { - // TODO - } - }); + // Show the modal + exportProjectsModal.modal('show'); + }, + error: function() { + // TODO + } }); + }); // Remove modal content when modal window is closed. exportProjectsModal.on('hidden.bs.modal', function() { diff --git a/app/models/concerns/variables_model.rb b/app/models/concerns/variables_model.rb index 637161b8e..8250c5852 100644 --- a/app/models/concerns/variables_model.rb +++ b/app/models/concerns/variables_model.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true. + module VariablesModel extend ActiveSupport::Concern diff --git a/app/models/user.rb b/app/models/user.rb index 96cc4dc5e..3db082f19 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,6 +1,9 @@ class User < ApplicationRecord - include SearchableModel, SettingsModel, VariablesModel - include User::TeamRoles, User::ProjectRoles + include SearchableModel + include SettingsModel + include VariablesModel + include User::TeamRoles + include User::ProjectRoles acts_as_token_authenticatable devise :invitable, :confirmable, :database_authenticatable, :registerable, diff --git a/db/migrate/20180930205254_add_variables_to_users.rb b/db/migrate/20180930205254_add_variables_to_users.rb index 9b40123fa..812f5a7e2 100644 --- a/db/migrate/20180930205254_add_variables_to_users.rb +++ b/db/migrate/20180930205254_add_variables_to_users.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddVariablesToUsers < ActiveRecord::Migration[5.1] def up add_column :users, :variables, :jsonb, default: {}, null: false From 398f4a7930847064c22edbeea4bb72d1b0562e47 Mon Sep 17 00:00:00 2001 From: Jure Grabnar Date: Fri, 12 Oct 2018 00:56:48 +0200 Subject: [PATCH 4/7] Fix formatting according to Houndbot --- app/assets/javascripts/projects/index.js | 3 +-- app/models/concerns/variables_model.rb | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/projects/index.js b/app/assets/javascripts/projects/index.js index 9defd81df..78f226c91 100644 --- a/app/assets/javascripts/projects/index.js +++ b/app/assets/javascripts/projects/index.js @@ -218,9 +218,8 @@ * Initialize the JS for export projects modal to work. */ function initExportProjectsModal() { - $exportProjectsBtn = $('#export-projects-button') + var $exportProjectsBtn = $('#export-projects-button'); $exportProjectsBtn.click(function() { - // Load HTML to refresh users list $.ajax({ url: $exportProjectsBtn.data('export-projects-url'), diff --git a/app/models/concerns/variables_model.rb b/app/models/concerns/variables_model.rb index 8250c5852..3bc3b8268 100644 --- a/app/models/concerns/variables_model.rb +++ b/app/models/concerns/variables_model.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: true. +# frozen_string_literal: true module VariablesModel extend ActiveSupport::Concern From 38dc07353ebe93470ef23d3234644a13e87d041f Mon Sep 17 00:00:00 2001 From: Jure Grabnar Date: Mon, 15 Oct 2018 14:25:12 +0200 Subject: [PATCH 5/7] Fix reviewers errors --- app/controllers/teams_controller.rb | 11 ++++------- app/views/projects/export/_error.html.erb | 2 +- app/views/projects/index.html.erb | 2 +- lib/tasks/exportable_items.rake | 5 +++-- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/app/controllers/teams_controller.rb b/app/controllers/teams_controller.rb index 81427015b..67364efb4 100644 --- a/app/controllers/teams_controller.rb +++ b/app/controllers/teams_controller.rb @@ -5,7 +5,7 @@ class TeamsController < ApplicationController before_action :check_create_samples_permissions, only: %i(parse_sheet import_samples) before_action :check_view_samples_permission, only: [:export_samples] - before_action :check_export_projects_permissions, only: [:export_projects] + before_action :check_export_projects_permissions, only: :export_projects def parse_sheet session[:return_to] ||= request.referer @@ -228,8 +228,9 @@ class TeamsController < ApplicationController def export_projects if export_projects_params[:project_ids] # Check if user has enough requests for the day - limit = ENV['EXPORT_ALL_LIMIT_24_HOURS'].to_i || 3 - if current_user.export_vars['num_of_export_all_last_24_hours'] >= limit + limit = (ENV['EXPORT_ALL_LIMIT_24_HOURS'] || 3).to_i + if limit.zero? \ + || current_user.export_vars['num_of_export_all_last_24_hours'] >= limit render json: { html: render_to_string( partial: 'projects/export/error.html.erb', @@ -254,11 +255,7 @@ class TeamsController < ApplicationController title: t('projects.export_projects.modal_title_success') } end - return - else - flash[:alert] = t('zip_export.export_error') end - redirect_back(fallback_location: root_path) end def routing_error(error = 'Routing error', status = :not_found, exception=nil) diff --git a/app/views/projects/export/_error.html.erb b/app/views/projects/export/_error.html.erb index 2f1bd5365..58896de9c 100644 --- a/app/views/projects/export/_error.html.erb +++ b/app/views/projects/export/_error.html.erb @@ -2,5 +2,5 @@ It looks like you have exceeded your daily export limit. The number of exports is limited to <%= limit %> requests per day - you currently have 0 export requests left.

-

Please repeat the desired action tomorrow, when your daily limit will rise back to <%= limit %> export requests. +

Please repeat the desired action tomorrow, when your daily limit will reset back to <%= limit %> export requests.

diff --git a/app/views/projects/index.html.erb b/app/views/projects/index.html.erb index 0a57952b4..706004343 100644 --- a/app/views/projects/index.html.erb +++ b/app/views/projects/index.html.erb @@ -88,7 +88,7 @@ diff --git a/lib/tasks/exportable_items.rake b/lib/tasks/exportable_items.rake index 2f9946b6e..04f9130f3 100644 --- a/lib/tasks/exportable_items.rake +++ b/lib/tasks/exportable_items.rake @@ -9,7 +9,7 @@ namespace :exportable_items do desc 'Resets export project counter to 0' task reset_export_projects_counter: :environment do - User.all.each do |user| + User.find_each do |user| User.transaction do begin user.export_vars['num_of_export_all_last_24_hours'] = 0 @@ -17,7 +17,8 @@ namespace :exportable_items do rescue ActiveRecord::ActiveRecordError, ArgumentError, ActiveRecord::RecordNotSaved => e - puts "Error creating user, transaction reverted: #{e}" + puts "Error resetting users num_of_export_all_last_24_hours " \ + "variable to 0, transaction reverted: #{e}" end end end From afbe70a2e253d94890cec6bb45800930161c89fa Mon Sep 17 00:00:00 2001 From: Jure Grabnar Date: Mon, 15 Oct 2018 21:40:59 +0200 Subject: [PATCH 6/7] Disable/enable export proejct button Fix filesystem saving --- app/assets/javascripts/projects/index.js | 16 +++++++++++++--- app/models/team_zip_export.rb | 13 ++++++++----- spec/models/user_spec.rb | 5 +++++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/app/assets/javascripts/projects/index.js b/app/assets/javascripts/projects/index.js index 78f226c91..15a6e8a2f 100644 --- a/app/assets/javascripts/projects/index.js +++ b/app/assets/javascripts/projects/index.js @@ -30,6 +30,7 @@ var exportProjectsModal = null; var exportProjectsModalHeader = null; var exportProjectsModalBody = null; + var exportProjectsBtn = null; var projectsViewMode = 'cards'; var projectsViewFilter = $('.projects-view-filter.active').data('filter'); @@ -218,11 +219,10 @@ * Initialize the JS for export projects modal to work. */ function initExportProjectsModal() { - var $exportProjectsBtn = $('#export-projects-button'); - $exportProjectsBtn.click(function() { + exportProjectsBtn.click(function() { // Load HTML to refresh users list $.ajax({ - url: $exportProjectsBtn.data('export-projects-url'), + url: exportProjectsBtn.data('export-projects-url'), type: 'POST', dataType: 'json', data: { @@ -339,6 +339,8 @@ exportProjectsModal = $('#export-projects-modal'); exportProjectsModalHeader = exportProjectsModal.find('.modal-title'); exportProjectsModalBody = exportProjectsModal.find('.modal-body'); + exportProjectsBtn = $('#export-projects-button'); + exportProjectsBtn.addClass('disabled'); updateSelectedCards(); initNewProjectModal(); @@ -361,10 +363,14 @@ if (this.checked && index === -1) { $(this).closest('.panel-project').addClass('selected'); selectedProjects.push(projectId); + exportProjectsBtn.removeClass('disabled'); // Otherwise, if checkbox is not checked and ID is in list of selected IDs } else if (!this.checked && index !== -1) { $(this).closest('.panel-project').removeClass('selected'); selectedProjects.splice(index, 1); + + if (selectedProjects.length == 0) + exportProjectsBtn.addClass('disabled'); } }); @@ -530,9 +536,13 @@ // If checkbox is checked and row ID is not in list of selected project IDs if (this.checked && index === -1) { selectedProjects.push(rowId); + exportProjectsBtn.removeClass('disabled'); // Otherwise, if checkbox is not checked and ID is in list of selected IDs } else if (!this.checked && index !== -1) { selectedProjects.splice(index, 1); + + if (selectedProjects.length == 0) + exportProjectsBtn.addClass('disabled'); } updateDataTableSelectAllCtrl(); diff --git a/app/models/team_zip_export.rb b/app/models/team_zip_export.rb index c702b4b11..6d07ae7d8 100644 --- a/app/models/team_zip_export.rb +++ b/app/models/team_zip_export.rb @@ -3,11 +3,14 @@ require 'fileutils' require 'csv' class TeamZipExport < ZipExport - has_attached_file :zip_file, - path: '/zip_exports/:attachment/:id_partition/' \ - ':hash/:style/:filename' - validates_attachment :zip_file, - content_type: { content_type: 'application/zip' } + # Override path only for S3 + if ENV['PAPERCLIP_STORAGE'] == 's3' + has_attached_file :zip_file, + path: '/zip_exports/:attachment/:id_partition/' \ + ':hash/:style/:filename' + validates_attachment :zip_file, + content_type: { content_type: 'application/zip' } + end # Length of allowed name size MAX_NAME_SIZE = 20 diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 63524da50..167dabb5a 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -37,6 +37,7 @@ describe User, type: :model do it { should have_db_column :invited_by_type } it { should have_db_column :invitations_count } it { should have_db_column :settings } + it { should have_db_column :variables } it { should have_db_column :current_team_id } it { should have_db_column :authentication_token } end @@ -179,6 +180,10 @@ describe User, type: :model do it { is_expected.to respond_to(:system_message_email_notification) } end + describe 'user variables' do + it { is_expected.to respond_to(:export_vars) } + end + describe '#last_activities' do let!(:user) { create :user } let!(:project) { create :project } From 1c7cc9369c94a5b427a5ff631e1ec314a47b80ff Mon Sep 17 00:00:00 2001 From: Jure Grabnar Date: Mon, 15 Oct 2018 21:44:24 +0200 Subject: [PATCH 7/7] Fix formatting according to HoundBot --- app/assets/javascripts/projects/index.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/projects/index.js b/app/assets/javascripts/projects/index.js index 15a6e8a2f..439c7c280 100644 --- a/app/assets/javascripts/projects/index.js +++ b/app/assets/javascripts/projects/index.js @@ -369,8 +369,9 @@ $(this).closest('.panel-project').removeClass('selected'); selectedProjects.splice(index, 1); - if (selectedProjects.length == 0) + if (selectedProjects.length === 0) { exportProjectsBtn.addClass('disabled'); + } } }); @@ -541,8 +542,9 @@ } else if (!this.checked && index !== -1) { selectedProjects.splice(index, 1); - if (selectedProjects.length == 0) + if (selectedProjects.length === 0) { exportProjectsBtn.addClass('disabled'); + } } updateDataTableSelectAllCtrl();