From 2d118da55c3ba674b541b478bdc6a54c7be714f9 Mon Sep 17 00:00:00 2001
From: Gregor Schmidt
Date: Tue, 20 Feb 2018 15:54:37 +0100
Subject: [PATCH 1/3] Generalize issues imports
Extend import controller to support arbitrary imports based on Import
subclasses. This way, we may add other kinds of imports, by providing some views
and a custom import class. This may also be done from within plugins.
---
app/controllers/imports_controller.rb | 44 ++++++++++++++++++++--
app/helpers/imports_helper.rb | 8 ++++
app/models/import.rb | 12 ++++++
app/models/issue_import.rb | 7 ++++
...ng.html.erb => _issues_fields_mapping.html.erb} | 2 +-
app/views/imports/_issues_mapping.html.erb | 16 ++++++++
app/views/imports/_issues_mapping.js.erb | 1 +
app/views/imports/_issues_saved_objects.html.erb | 7 ++++
app/views/imports/_issues_sidebar.html.erb | 3 ++
app/views/imports/mapping.html.erb | 23 ++---------
app/views/imports/mapping.js.erb | 2 +-
app/views/imports/new.html.erb | 7 ++--
app/views/imports/run.html.erb | 6 +--
app/views/imports/settings.html.erb | 6 +--
app/views/imports/show.html.erb | 14 ++-----
config/routes.rb | 2 +-
lib/redmine.rb | 2 +-
test/functional/imports_controller_test.rb | 3 +-
test/integration/routing/imports_test.rb | 3 +-
test/unit/issue_import_test.rb | 6 +++
20 files changed, 121 insertions(+), 53 deletions(-)
rename app/views/imports/{_fields_mapping.html.erb => _issues_fields_mapping.html.erb} (97%)
create mode 100644 app/views/imports/_issues_mapping.html.erb
create mode 100644 app/views/imports/_issues_mapping.js.erb
create mode 100644 app/views/imports/_issues_saved_objects.html.erb
create mode 100644 app/views/imports/_issues_sidebar.html.erb
diff --git a/app/controllers/imports_controller.rb b/app/controllers/imports_controller.rb
index 661eb7405..271b015cc 100644
--- a/app/controllers/imports_controller.rb
+++ b/app/controllers/imports_controller.rb
@@ -18,19 +18,20 @@
require 'csv'
class ImportsController < ApplicationController
- menu_item :issues
-
before_action :find_import, :only => [:show, :settings, :mapping, :run]
- before_action :authorize_global
+ before_action :authorize_import
+
+ layout :import_layout
helper :issues
helper :queries
def new
+ @import = import_type.new
end
def create
- @import = IssueImport.new
+ @import = import_type.new
@import.user = User.current
@import.file = params[:file]
@import.set_default_settings
@@ -94,6 +95,14 @@ class ImportsController < ApplicationController
end
end
+ def current_menu(project)
+ if import_layout == 'admin'
+ nil
+ else
+ :application_menu
+ end
+ end
+
private
def find_import
@@ -119,4 +128,31 @@ class ImportsController < ApplicationController
def max_items_per_request
5
end
+
+ def import_layout
+ import_type && import_type.layout || 'base'
+ end
+
+ def menu_items
+ menu_item = import_type ? import_type.menu_item : nil
+
+ { self.controller_name.to_sym => { :actions => {}, :default => menu_item } }
+ end
+
+ def authorize_import
+ return render_404 unless import_type
+ return render_403 unless import_type.authorized?(User.current)
+ end
+
+ def import_type
+ return @import_type if defined? @import_type
+
+ @import_type =
+ if @import
+ @import.class
+ else
+ type = Object.const_get(params[:type]) rescue nil
+ type && type < Import ? type : nil
+ end
+ end
end
diff --git a/app/helpers/imports_helper.rb b/app/helpers/imports_helper.rb
index 39f3b95ab..1a4836519 100644
--- a/app/helpers/imports_helper.rb
+++ b/app/helpers/imports_helper.rb
@@ -18,6 +18,14 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
module ImportsHelper
+ def import_title
+ l(:"label_import_#{import_partial_prefix}")
+ end
+
+ def import_partial_prefix
+ @import.class.name.sub('Import', '').underscore.pluralize
+ end
+
def options_for_mapping_select(import, field, options={})
tags = "".html_safe
blank_text = options[:required] ? "-- #{l(:actionview_instancetag_blank_option)} --" : " ".html_safe
diff --git a/app/models/import.rb b/app/models/import.rb
index d2c53baac..194f46aa9 100644
--- a/app/models/import.rb
+++ b/app/models/import.rb
@@ -35,6 +35,18 @@ class Import < ActiveRecord::Base
'%d-%m-%Y'
]
+ def self.menu_item
+ nil
+ end
+
+ def self.layout
+ 'base'
+ end
+
+ def self.authorized?(user)
+ user.admin?
+ end
+
def initialize(*args)
super
self.settings ||= {}
diff --git a/app/models/issue_import.rb b/app/models/issue_import.rb
index ad04c0be5..3e193ee3a 100644
--- a/app/models/issue_import.rb
+++ b/app/models/issue_import.rb
@@ -16,6 +16,13 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class IssueImport < Import
+ def self.menu_item
+ :issues
+ end
+
+ def self.authorized?(user)
+ user.allowed_to?(:import_issues, nil, :global => true)
+ end
# Returns the objects that were imported
def saved_objects
diff --git a/app/views/imports/_fields_mapping.html.erb b/app/views/imports/_issues_fields_mapping.html.erb
similarity index 97%
rename from app/views/imports/_fields_mapping.html.erb
rename to app/views/imports/_issues_fields_mapping.html.erb
index f59350116..542a956ff 100644
--- a/app/views/imports/_fields_mapping.html.erb
+++ b/app/views/imports/_issues_fields_mapping.html.erb
@@ -54,7 +54,7 @@
<% @custom_fields.each do |field| %>
-
+
<%= mapping_select_tag @import, "cf_#{field.id}" %>
<% end %>
diff --git a/app/views/imports/_issues_mapping.html.erb b/app/views/imports/_issues_mapping.html.erb
new file mode 100644
index 000000000..dc97d9c3a
--- /dev/null
+++ b/app/views/imports/_issues_mapping.html.erb
@@ -0,0 +1,16 @@
+
+
+<%= javascript_tag do %>
+ $('#fields-mapping').on('change', '#import_mapping_project_id, #import_mapping_tracker', function(){
+ $.ajax({
+ url: '<%= import_mapping_path(@import, :format => 'js') %>',
+ type: 'post',
+ data: $('#import-form').serialize()
+ });
+ });
+<% end %>
diff --git a/app/views/imports/_issues_mapping.js.erb b/app/views/imports/_issues_mapping.js.erb
new file mode 100644
index 000000000..012ccc537
--- /dev/null
+++ b/app/views/imports/_issues_mapping.js.erb
@@ -0,0 +1 @@
+$('#fields-mapping').html('<%= escape_javascript(render :partial => 'issues_fields_mapping') %>');
diff --git a/app/views/imports/_issues_saved_objects.html.erb b/app/views/imports/_issues_saved_objects.html.erb
new file mode 100644
index 000000000..f708a1c23
--- /dev/null
+++ b/app/views/imports/_issues_saved_objects.html.erb
@@ -0,0 +1,7 @@
+
+ <% saved_objects.each do |issue| %>
+ - <%= link_to_issue issue %>
+ <% end %>
+
+
+<%= link_to l(:label_issue_view_all), issues_path(:set_filter => 1, :status_id => '*', :issue_id => saved_objects.map(&:id).join(',')) %>
diff --git a/app/views/imports/_issues_sidebar.html.erb b/app/views/imports/_issues_sidebar.html.erb
new file mode 100644
index 000000000..e098175ec
--- /dev/null
+++ b/app/views/imports/_issues_sidebar.html.erb
@@ -0,0 +1,3 @@
+<% content_for :sidebar do %>
+ <%= render :partial => 'issues/sidebar' %>
+<% end %>
diff --git a/app/views/imports/mapping.html.erb b/app/views/imports/mapping.html.erb
index 2e225d6c2..1822f2802 100644
--- a/app/views/imports/mapping.html.erb
+++ b/app/views/imports/mapping.html.erb
@@ -1,12 +1,7 @@
-<%= l(:label_import_issues) %>
+<%= import_title %>
<%= form_tag(import_mapping_path(@import), :id => "import-form") do %>
-
+ <%= render :partial => "#{import_partial_prefix}_mapping" %>