summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorGo MAEDA <maeda@farend.jp>2019-05-09 07:40:06 +0000
committerGo MAEDA <maeda@farend.jp>2019-05-09 07:40:06 +0000
commitb540046ed7084ba50f5ca280f3ffae0751af8142 (patch)
tree4bc946090d4940a219e84f70ca72c5655de5be42 /app
parentbcc60805c97104f44a37b92321d7aa1e5c51b622 (diff)
downloadredmine-b540046ed7084ba50f5ca280f3ffae0751af8142.tar.gz
redmine-b540046ed7084ba50f5ca280f3ffae0751af8142.zip
Generalize issues imports (#28234).
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. Patch by Gregor Schmidt. git-svn-id: http://svn.redmine.org/redmine/trunk@18145 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app')
-rw-r--r--app/controllers/imports_controller.rb44
-rw-r--r--app/helpers/imports_helper.rb8
-rw-r--r--app/models/import.rb12
-rw-r--r--app/models/issue_import.rb7
-rw-r--r--app/views/imports/_issues_fields_mapping.html.erb (renamed from app/views/imports/_fields_mapping.html.erb)2
-rw-r--r--app/views/imports/_issues_mapping.html.erb16
-rw-r--r--app/views/imports/_issues_mapping.js.erb1
-rw-r--r--app/views/imports/_issues_saved_objects.html.erb7
-rw-r--r--app/views/imports/_issues_sidebar.html.erb3
-rw-r--r--app/views/imports/mapping.html.erb23
-rw-r--r--app/views/imports/mapping.js.erb2
-rw-r--r--app/views/imports/new.html.erb7
-rw-r--r--app/views/imports/run.html.erb6
-rw-r--r--app/views/imports/settings.html.erb6
-rw-r--r--app/views/imports/show.html.erb14
15 files changed, 109 insertions, 49 deletions
diff --git a/app/controllers/imports_controller.rb b/app/controllers/imports_controller.rb
index 54c739cca..fa02318bc 100644
--- a/app/controllers/imports_controller.rb
+++ b/app/controllers/imports_controller.rb
@@ -20,19 +20,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
@@ -98,6 +99,14 @@ class ImportsController < ApplicationController
end
end
+ def current_menu(project)
+ if import_layout == 'admin'
+ nil
+ else
+ :application_menu
+ end
+ end
+
private
def find_import
@@ -123,4 +132,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 22f070cf5..b97576d6f 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)} --" : "&nbsp;".html_safe
diff --git a/app/models/import.rb b/app/models/import.rb
index 7009f2e7e..df6b085a6 100644
--- a/app/models/import.rb
+++ b/app/models/import.rb
@@ -37,6 +37,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 6c59b26db..5a3542291 100644
--- a/app/models/issue_import.rb
+++ b/app/models/issue_import.rb
@@ -18,6 +18,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
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 @@
</p>
<% @custom_fields.each do |field| %>
<p>
- <label for="import_mapping_cf_<% field.id %>"><%= field.name %></label>
+ <label for="import_mapping_cf_<%= field.id %>"><%= field.name %></label>
<%= mapping_select_tag @import, "cf_#{field.id}" %>
</p>
<% 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 @@
+<fieldset class="box tabular">
+ <legend><%= l(:label_fields_mapping) %></legend>
+ <div id="fields-mapping">
+ <%= render :partial => 'issues_fields_mapping' %>
+ </div>
+</fieldset>
+
+<%= 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 @@
+<ul id="saved-items">
+ <% saved_objects.each do |issue| %>
+ <li><%= link_to_issue issue %></li>
+ <% end %>
+</ul>
+
+<p><%= link_to l(:label_issue_view_all), issues_path(:set_filter => 1, :status_id => '*', :issue_id => saved_objects.map(&:id).join(',')) %></p>
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 @@
-<h2><%= l(:label_import_issues) %></h2>
+<h2><%= import_title %></h2>
<%= form_tag(import_mapping_path(@import), :id => "import-form") do %>
- <fieldset class="box tabular">
- <legend><%= l(:label_fields_mapping) %></legend>
- <div id="fields-mapping">
- <%= render :partial => 'fields_mapping' %>
- </div>
- </fieldset>
+ <%= render :partial => "#{import_partial_prefix}_mapping" %>
<div class="autoscroll">
<fieldset class="box">
@@ -28,25 +23,13 @@
</p>
<% end %>
-<% content_for :sidebar do %>
- <%= render :partial => 'issues/sidebar' %>
-<% end %>
-
+<%= render :partial => "#{import_partial_prefix}_sidebar" %>
<%= javascript_tag do %>
$(document).ready(function() {
- $('#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()
- });
- });
-
$('#import-form').submit(function(){
$('#import-details').show().addClass('ajax-loading');
$('#import-progress').progressbar({value: 0, max: <%= @import.total_items || 0 %>});
});
-
});
<% end %>
diff --git a/app/views/imports/mapping.js.erb b/app/views/imports/mapping.js.erb
index 8fdf14a36..4a4358427 100644
--- a/app/views/imports/mapping.js.erb
+++ b/app/views/imports/mapping.js.erb
@@ -1 +1 @@
-$('#fields-mapping').html('<%= escape_javascript(render :partial => 'fields_mapping') %>');
+<%= render :partial => "#{import_partial_prefix}_mapping" %>
diff --git a/app/views/imports/new.html.erb b/app/views/imports/new.html.erb
index e20be353a..41b27d6c9 100644
--- a/app/views/imports/new.html.erb
+++ b/app/views/imports/new.html.erb
@@ -1,6 +1,7 @@
-<h2><%= l(:label_import_issues) %></h2>
+<h2><%= import_title %></h2>
<%= form_tag(imports_path, :multipart => true) do %>
+ <%= hidden_field_tag 'type', @import.type %>
<fieldset class="box">
<legend><%= l(:label_select_file_to_import) %> (CSV)</legend>
<p>
@@ -10,6 +11,4 @@
<p><%= submit_tag l(:label_next).html_safe + " &#187;".html_safe, :name => nil %></p>
<% end %>
-<% content_for :sidebar do %>
- <%= render :partial => 'issues/sidebar' %>
-<% end %>
+<%= render :partial => "#{import_partial_prefix}_sidebar" %>
diff --git a/app/views/imports/run.html.erb b/app/views/imports/run.html.erb
index 2a723537e..50b47836d 100644
--- a/app/views/imports/run.html.erb
+++ b/app/views/imports/run.html.erb
@@ -1,12 +1,10 @@
-<h2><%= l(:label_import_issues) %></h2>
+<h2><%= import_title %></h2>
<div id="import-details">
<div id="import-progress"><div id="progress-label">0 / <%= @import.total_items.to_i %></div></div>
</div>
-<% content_for :sidebar do %>
- <%= render :partial => 'issues/sidebar' %>
-<% end %>
+<%= render :partial => "#{import_partial_prefix}_sidebar" %>
<%= javascript_tag do %>
$(document).ready(function() {
diff --git a/app/views/imports/settings.html.erb b/app/views/imports/settings.html.erb
index 6edfb10af..0fbb01857 100644
--- a/app/views/imports/settings.html.erb
+++ b/app/views/imports/settings.html.erb
@@ -1,4 +1,4 @@
-<h2><%= l(:label_import_issues) %></h2>
+<h2><%= import_title %></h2>
<%= form_tag(import_settings_path(@import), :id => "import-form") do %>
<fieldset class="box tabular">
@@ -25,6 +25,4 @@
<p><%= submit_tag l(:label_next).html_safe + " &#187;".html_safe, :name => nil %></p>
<% end %>
-<% content_for :sidebar do %>
- <%= render :partial => 'issues/sidebar' %>
-<% end %>
+<%= render :partial => "#{import_partial_prefix}_sidebar" %>
diff --git a/app/views/imports/show.html.erb b/app/views/imports/show.html.erb
index 19c874c91..ca963ab37 100644
--- a/app/views/imports/show.html.erb
+++ b/app/views/imports/show.html.erb
@@ -1,15 +1,9 @@
-<h2><%= l(:label_import_issues) %></h2>
+<h2><%= import_title %></h2>
<% if @import.saved_items.count > 0 %>
<p><%= l(:notice_import_finished, :count => @import.saved_items.count) %>:</p>
- <ul id="saved-items">
- <% @import.saved_objects.each do |issue| %>
- <li><%= link_to_issue issue %></li>
- <% end %>
- </ul>
-
- <p><%= link_to l(:label_issue_view_all), issues_path(:set_filter => 1, :status_id => '*', :issue_id => @import.saved_objects.map(&:id).join(',')) %></p>
+ <%= render :partial => "#{import_partial_prefix}_saved_objects", :locals => { saved_objects: @import.saved_objects } %>
<% end %>
<% if @import.unsaved_items.count > 0 %>
@@ -33,6 +27,4 @@
</table>
<% end %>
-<% content_for :sidebar do %>
- <%= render :partial => 'issues/sidebar' %>
-<% end %>
+<%= render :partial => "#{import_partial_prefix}_sidebar" %>