From b94d2c5c03c0997258351af2da625f05d05b9bf4 Mon Sep 17 00:00:00 2001 From: Luka Murn Date: Tue, 30 May 2017 08:57:00 +0200 Subject: [PATCH 1/3] Implement 'copy' method on Repository object --- app/models/repository.rb | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/app/models/repository.rb b/app/models/repository.rb index 43977d3cf..abaf8114a 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -13,4 +13,31 @@ class Repository < ActiveRecord::Base length: { maximum: Constants::NAME_MAX_LENGTH } validates :team, presence: true validates :created_by, presence: true + + def copy(created_by, name) + new_repo = nil + + begin + Repository.transaction do + # Clone the repository object + new_repo = dup + new_repo.created_by = created_by + new_repo.name = name + new_repo.save! + + # Clone columns (only if new_repo was saved) + repository_columns.find_each do |col| + new_col = col.dup + new_col.repository = new_repo + new_col.created_by = created_by + new_col.save! + end + end + rescue ActiveRecord::RecordInvalid + return false + end + + # If everything is okay, return new_repo + new_repo + end end From 38361e4bb447379f5f099800bc35dcd1c4315d47 Mon Sep 17 00:00:00 2001 From: Luka Murn Date: Wed, 7 Jun 2017 18:43:48 +0200 Subject: [PATCH 2/3] Setup initial GUI --- app/assets/javascripts/repositories/index.js | 1 + app/helpers/permission_helper.rb | 4 ++++ app/views/repositories/index.html.erb | 24 ++++++++++++++------ config/locales/en.yml | 1 + config/routes.rb | 2 ++ 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/repositories/index.js b/app/assets/javascripts/repositories/index.js index 0c7b64f88..1a7249509 100644 --- a/app/assets/javascripts/repositories/index.js +++ b/app/assets/javascripts/repositories/index.js @@ -3,5 +3,6 @@ $('.delete-repo-option').initializeModal('#delete-repo-modal'); $('.rename-repo-option').initializeModal('#rename-repo-modal'); + $('.copy-repo-option').initializeModal('#copy-repo-modal'); $('.create-repository').initializeModal('#create-repo-modal'); })(); diff --git a/app/helpers/permission_helper.rb b/app/helpers/permission_helper.rb index 6b3791fad..d2b264af5 100644 --- a/app/helpers/permission_helper.rb +++ b/app/helpers/permission_helper.rb @@ -1070,6 +1070,10 @@ module PermissionHelper is_admin_of_team(repository.team) end + def can_copy_repository(repository) + can_create_repository(repository.team) + end + def can_create_columns_in_repository(repository) is_normal_user_or_admin_of_team(repository.team) end diff --git a/app/views/repositories/index.html.erb b/app/views/repositories/index.html.erb index 75e55c06e..498f78064 100644 --- a/app/views/repositories/index.html.erb +++ b/app/views/repositories/index.html.erb @@ -51,17 +51,27 @@ - <% if can_edit_and_destroy_repository repo %> - diff --git a/config/locales/en.yml b/config/locales/en.yml index 6eb7b813a..c2a85191f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -849,6 +849,7 @@ en: options_dropdown: header: "Edit repository" rename: "Rename" + copy: "Copy" delete: "Delete" modal_delete: title_html: "Delete repository %{name}" diff --git a/config/routes.rb b/config/routes.rb index 1abb6b78a..033868d7a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -132,6 +132,8 @@ Rails.application.routes.draw do defaults: { format: 'json' } get 'rename_modal', to: 'repositories#rename_modal', defaults: { format: 'json' } + get 'copy_modal', to: 'repositories#copy_modal', + defaults: { format: 'json' } end resources :samples, only: [:new, :create] resources :sample_types, except: [:show, :new] do From 61eb52f86f0843b19fbf908b62cf9067fb29c4d8 Mon Sep 17 00:00:00 2001 From: Luka Murn Date: Wed, 7 Jun 2017 19:11:25 +0200 Subject: [PATCH 3/3] Implement GUI for copying repositories Closes SCI.1270. --- app/controllers/repositories_controller.rb | 58 +++++++++++++++++++ app/models/repository_table_state.rb | 1 + .../_copy_repository_modal.html.erb | 32 ++++++++++ config/locales/en.yml | 6 ++ config/routes.rb | 2 + 5 files changed, 99 insertions(+) create mode 100644 app/views/repositories/_copy_repository_modal.html.erb diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index a13947d90..66a4410ad 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -3,6 +3,8 @@ class RepositoriesController < ApplicationController before_action :check_view_all_permissions, only: :index before_action :check_edit_and_destroy_permissions, only: %(destroy destroy_modal rename_modal update) + before_action :check_copy_permissions, only: + %(copy_modal copy) before_action :check_create_permissions, only: %(create_new_modal create) @@ -99,6 +101,58 @@ class RepositoriesController < ApplicationController end end + def copy_modal + @repository = Repository.find(params[:repository_id]) + @tmp_repository = Repository.new( + team: @team, + created_by: current_user, + name: @repository.name + ) + respond_to do |format| + format.json do + render json: { + html: render_to_string( + partial: 'copy_repository_modal.html.erb' + ) + } + end + end + end + + def copy + @repository = Repository.find(params[:repository_id]) + @tmp_repository = Repository.new( + team: @team, + created_by: current_user + ) + @tmp_repository.assign_attributes(repository_params) + + respond_to do |format| + format.json do + if !@tmp_repository.valid? + render json: @tmp_repository.errors, status: :unprocessable_entity + else + copied_repository = + @repository.copy(current_user, @tmp_repository.name) + + if !copied_repository + render json: { 'name': ['Server error'] }, + status: :unprocessable_entity + else + flash[:success] = t( + 'repositories.index.copy_flash', + old: @repository.name, + new: copied_repository.name + ) + render json: { + url: team_repositories_path(repository: copied_repository) + }, status: :ok + end + end + end + end + end + # AJAX actions def repository_table_index @repository = Repository.find_by_id(params[:repository_id]) @@ -137,6 +191,10 @@ class RepositoriesController < ApplicationController render_403 unless can_edit_and_destroy_repository(@repository) end + def check_copy_permissions + render_403 unless can_copy_repository(@repository) + end + def repository_params params.require(:repository).permit(:name) end diff --git a/app/models/repository_table_state.rb b/app/models/repository_table_state.rb index af85487be..27af3e2d1 100644 --- a/app/models/repository_table_state.rb +++ b/app/models/repository_table_state.rb @@ -18,6 +18,7 @@ class RepositoryTableState < ActiveRecord::Base user: user, repository: custom_column.repository ) + return if table_state.empty? repository_state = table_state.first['state'] if column_index # delete column diff --git a/app/views/repositories/_copy_repository_modal.html.erb b/app/views/repositories/_copy_repository_modal.html.erb new file mode 100644 index 000000000..8d01d60d4 --- /dev/null +++ b/app/views/repositories/_copy_repository_modal.html.erb @@ -0,0 +1,32 @@ + diff --git a/config/locales/en.yml b/config/locales/en.yml index c2a85191f..231233a0e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -843,6 +843,7 @@ en: add_new_repository_tab: "Create new repository" delete_flash: "\"%{name}\" repository was successfully deleted!" rename_flash: "\"%{old_name}\" repository was successfully renamed to \"%{new_name}\"!" + copy_flash: "\"%{new}\" repository was successfully copied from \"%{old}\"!" no_teams: title: "Your dashboard is empty!" text: "It seems you're not a member of any team. See team management to sort it out." @@ -863,6 +864,11 @@ en: name: "New repository name" name_placeholder: "My repository" rename: "Rename repository" + modal_copy: + title_html: "Copy repository %{name}" + name: "New repository name" + name_placeholder: "My repository" + copy: "Copy repository" modal_create: title: "Create new repository" name_label: "Repository name" diff --git a/config/routes.rb b/config/routes.rb index 033868d7a..d08666ab5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -134,6 +134,8 @@ Rails.application.routes.draw do defaults: { format: 'json' } get 'copy_modal', to: 'repositories#copy_modal', defaults: { format: 'json' } + post 'copy', to: 'repositories#copy', + defaults: { format: 'json' } end resources :samples, only: [:new, :create] resources :sample_types, except: [:show, :new] do