##// END OF EJS Templates
Menu items mapping....
Jean-Philippe Lang -
r15695:4ee4fad19ae4
parent child
Show More
@@ -1,121 +1,122
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require 'csv'
18 require 'csv'
19
19
20 class ImportsController < ApplicationController
20 class ImportsController < ApplicationController
21 menu_item :issues
21
22
22 before_action :find_import, :only => [:show, :settings, :mapping, :run]
23 before_action :find_import, :only => [:show, :settings, :mapping, :run]
23 before_action :authorize_global
24 before_action :authorize_global
24
25
25 helper :issues
26 helper :issues
26 helper :queries
27 helper :queries
27
28
28 def new
29 def new
29 end
30 end
30
31
31 def create
32 def create
32 @import = IssueImport.new
33 @import = IssueImport.new
33 @import.user = User.current
34 @import.user = User.current
34 @import.file = params[:file]
35 @import.file = params[:file]
35 @import.set_default_settings
36 @import.set_default_settings
36
37
37 if @import.save
38 if @import.save
38 redirect_to import_settings_path(@import)
39 redirect_to import_settings_path(@import)
39 else
40 else
40 render :action => 'new'
41 render :action => 'new'
41 end
42 end
42 end
43 end
43
44
44 def show
45 def show
45 end
46 end
46
47
47 def settings
48 def settings
48 if request.post? && @import.parse_file
49 if request.post? && @import.parse_file
49 redirect_to import_mapping_path(@import)
50 redirect_to import_mapping_path(@import)
50 end
51 end
51
52
52 rescue CSV::MalformedCSVError => e
53 rescue CSV::MalformedCSVError => e
53 flash.now[:error] = l(:error_invalid_csv_file_or_settings)
54 flash.now[:error] = l(:error_invalid_csv_file_or_settings)
54 rescue ArgumentError, Encoding::InvalidByteSequenceError => e
55 rescue ArgumentError, Encoding::InvalidByteSequenceError => e
55 flash.now[:error] = l(:error_invalid_file_encoding, :encoding => ERB::Util.h(@import.settings['encoding']))
56 flash.now[:error] = l(:error_invalid_file_encoding, :encoding => ERB::Util.h(@import.settings['encoding']))
56 rescue SystemCallError => e
57 rescue SystemCallError => e
57 flash.now[:error] = l(:error_can_not_read_import_file)
58 flash.now[:error] = l(:error_can_not_read_import_file)
58 end
59 end
59
60
60 def mapping
61 def mapping
61 @custom_fields = @import.mappable_custom_fields
62 @custom_fields = @import.mappable_custom_fields
62
63
63 if request.post?
64 if request.post?
64 respond_to do |format|
65 respond_to do |format|
65 format.html {
66 format.html {
66 if params[:previous]
67 if params[:previous]
67 redirect_to import_settings_path(@import)
68 redirect_to import_settings_path(@import)
68 else
69 else
69 redirect_to import_run_path(@import)
70 redirect_to import_run_path(@import)
70 end
71 end
71 }
72 }
72 format.js # updates mapping form on project or tracker change
73 format.js # updates mapping form on project or tracker change
73 end
74 end
74 end
75 end
75 end
76 end
76
77
77 def run
78 def run
78 if request.post?
79 if request.post?
79 @current = @import.run(
80 @current = @import.run(
80 :max_items => max_items_per_request,
81 :max_items => max_items_per_request,
81 :max_time => 10.seconds
82 :max_time => 10.seconds
82 )
83 )
83 respond_to do |format|
84 respond_to do |format|
84 format.html {
85 format.html {
85 if @import.finished?
86 if @import.finished?
86 redirect_to import_path(@import)
87 redirect_to import_path(@import)
87 else
88 else
88 redirect_to import_run_path(@import)
89 redirect_to import_run_path(@import)
89 end
90 end
90 }
91 }
91 format.js
92 format.js
92 end
93 end
93 end
94 end
94 end
95 end
95
96
96 private
97 private
97
98
98 def find_import
99 def find_import
99 @import = Import.where(:user_id => User.current.id, :filename => params[:id]).first
100 @import = Import.where(:user_id => User.current.id, :filename => params[:id]).first
100 if @import.nil?
101 if @import.nil?
101 render_404
102 render_404
102 return
103 return
103 elsif @import.finished? && action_name != 'show'
104 elsif @import.finished? && action_name != 'show'
104 redirect_to import_path(@import)
105 redirect_to import_path(@import)
105 return
106 return
106 end
107 end
107 update_from_params if request.post?
108 update_from_params if request.post?
108 end
109 end
109
110
110 def update_from_params
111 def update_from_params
111 if params[:import_settings].is_a?(Hash)
112 if params[:import_settings].is_a?(Hash)
112 @import.settings ||= {}
113 @import.settings ||= {}
113 @import.settings.merge!(params[:import_settings])
114 @import.settings.merge!(params[:import_settings])
114 @import.save!
115 @import.save!
115 end
116 end
116 end
117 end
117
118
118 def max_items_per_request
119 def max_items_per_request
119 5
120 5
120 end
121 end
121 end
122 end
@@ -1,240 +1,240
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class ProjectsController < ApplicationController
18 class ProjectsController < ApplicationController
19 menu_item :overview
19 menu_item :overview
20 menu_item :settings, :only => :settings
20 menu_item :settings, :only => :settings
21 menu_item :projects, :only => [:index, :new, :create]
21 menu_item :projects, :only => [:index, :new, :copy, :create]
22
22
23 before_action :find_project, :except => [ :index, :list, :new, :create, :copy ]
23 before_action :find_project, :except => [ :index, :list, :new, :create, :copy ]
24 before_action :authorize, :except => [ :index, :list, :new, :create, :copy, :archive, :unarchive, :destroy]
24 before_action :authorize, :except => [ :index, :list, :new, :create, :copy, :archive, :unarchive, :destroy]
25 before_action :authorize_global, :only => [:new, :create]
25 before_action :authorize_global, :only => [:new, :create]
26 before_action :require_admin, :only => [ :copy, :archive, :unarchive, :destroy ]
26 before_action :require_admin, :only => [ :copy, :archive, :unarchive, :destroy ]
27 accept_rss_auth :index
27 accept_rss_auth :index
28 accept_api_auth :index, :show, :create, :update, :destroy
28 accept_api_auth :index, :show, :create, :update, :destroy
29 require_sudo_mode :destroy
29 require_sudo_mode :destroy
30
30
31 helper :custom_fields
31 helper :custom_fields
32 helper :issues
32 helper :issues
33 helper :queries
33 helper :queries
34 helper :repositories
34 helper :repositories
35 helper :members
35 helper :members
36
36
37 # Lists visible projects
37 # Lists visible projects
38 def index
38 def index
39 scope = Project.visible.sorted
39 scope = Project.visible.sorted
40
40
41 respond_to do |format|
41 respond_to do |format|
42 format.html {
42 format.html {
43 unless params[:closed]
43 unless params[:closed]
44 scope = scope.active
44 scope = scope.active
45 end
45 end
46 @projects = scope.to_a
46 @projects = scope.to_a
47 }
47 }
48 format.js {
48 format.js {
49 if params[:q].present?
49 if params[:q].present?
50 @projects = Project.visible.like(params[:q]).to_a
50 @projects = Project.visible.like(params[:q]).to_a
51 else
51 else
52 @projects = User.current.projects.to_a
52 @projects = User.current.projects.to_a
53 end
53 end
54 }
54 }
55 format.api {
55 format.api {
56 @offset, @limit = api_offset_and_limit
56 @offset, @limit = api_offset_and_limit
57 @project_count = scope.count
57 @project_count = scope.count
58 @projects = scope.offset(@offset).limit(@limit).to_a
58 @projects = scope.offset(@offset).limit(@limit).to_a
59 }
59 }
60 format.atom {
60 format.atom {
61 projects = scope.reorder(:created_on => :desc).limit(Setting.feeds_limit.to_i).to_a
61 projects = scope.reorder(:created_on => :desc).limit(Setting.feeds_limit.to_i).to_a
62 render_feed(projects, :title => "#{Setting.app_title}: #{l(:label_project_latest)}")
62 render_feed(projects, :title => "#{Setting.app_title}: #{l(:label_project_latest)}")
63 }
63 }
64 end
64 end
65 end
65 end
66
66
67 def new
67 def new
68 @issue_custom_fields = IssueCustomField.sorted.to_a
68 @issue_custom_fields = IssueCustomField.sorted.to_a
69 @trackers = Tracker.sorted.to_a
69 @trackers = Tracker.sorted.to_a
70 @project = Project.new
70 @project = Project.new
71 @project.safe_attributes = params[:project]
71 @project.safe_attributes = params[:project]
72 end
72 end
73
73
74 def create
74 def create
75 @issue_custom_fields = IssueCustomField.sorted.to_a
75 @issue_custom_fields = IssueCustomField.sorted.to_a
76 @trackers = Tracker.sorted.to_a
76 @trackers = Tracker.sorted.to_a
77 @project = Project.new
77 @project = Project.new
78 @project.safe_attributes = params[:project]
78 @project.safe_attributes = params[:project]
79
79
80 if @project.save
80 if @project.save
81 unless User.current.admin?
81 unless User.current.admin?
82 @project.add_default_member(User.current)
82 @project.add_default_member(User.current)
83 end
83 end
84 respond_to do |format|
84 respond_to do |format|
85 format.html {
85 format.html {
86 flash[:notice] = l(:notice_successful_create)
86 flash[:notice] = l(:notice_successful_create)
87 if params[:continue]
87 if params[:continue]
88 attrs = {:parent_id => @project.parent_id}.reject {|k,v| v.nil?}
88 attrs = {:parent_id => @project.parent_id}.reject {|k,v| v.nil?}
89 redirect_to new_project_path(attrs)
89 redirect_to new_project_path(attrs)
90 else
90 else
91 redirect_to settings_project_path(@project)
91 redirect_to settings_project_path(@project)
92 end
92 end
93 }
93 }
94 format.api { render :action => 'show', :status => :created, :location => url_for(:controller => 'projects', :action => 'show', :id => @project.id) }
94 format.api { render :action => 'show', :status => :created, :location => url_for(:controller => 'projects', :action => 'show', :id => @project.id) }
95 end
95 end
96 else
96 else
97 respond_to do |format|
97 respond_to do |format|
98 format.html { render :action => 'new' }
98 format.html { render :action => 'new' }
99 format.api { render_validation_errors(@project) }
99 format.api { render_validation_errors(@project) }
100 end
100 end
101 end
101 end
102 end
102 end
103
103
104 def copy
104 def copy
105 @issue_custom_fields = IssueCustomField.sorted.to_a
105 @issue_custom_fields = IssueCustomField.sorted.to_a
106 @trackers = Tracker.sorted.to_a
106 @trackers = Tracker.sorted.to_a
107 @source_project = Project.find(params[:id])
107 @source_project = Project.find(params[:id])
108 if request.get?
108 if request.get?
109 @project = Project.copy_from(@source_project)
109 @project = Project.copy_from(@source_project)
110 @project.identifier = Project.next_identifier if Setting.sequential_project_identifiers?
110 @project.identifier = Project.next_identifier if Setting.sequential_project_identifiers?
111 else
111 else
112 Mailer.with_deliveries(params[:notifications] == '1') do
112 Mailer.with_deliveries(params[:notifications] == '1') do
113 @project = Project.new
113 @project = Project.new
114 @project.safe_attributes = params[:project]
114 @project.safe_attributes = params[:project]
115 if @project.copy(@source_project, :only => params[:only])
115 if @project.copy(@source_project, :only => params[:only])
116 flash[:notice] = l(:notice_successful_create)
116 flash[:notice] = l(:notice_successful_create)
117 redirect_to settings_project_path(@project)
117 redirect_to settings_project_path(@project)
118 elsif !@project.new_record?
118 elsif !@project.new_record?
119 # Project was created
119 # Project was created
120 # But some objects were not copied due to validation failures
120 # But some objects were not copied due to validation failures
121 # (eg. issues from disabled trackers)
121 # (eg. issues from disabled trackers)
122 # TODO: inform about that
122 # TODO: inform about that
123 redirect_to settings_project_path(@project)
123 redirect_to settings_project_path(@project)
124 end
124 end
125 end
125 end
126 end
126 end
127 rescue ActiveRecord::RecordNotFound
127 rescue ActiveRecord::RecordNotFound
128 # source_project not found
128 # source_project not found
129 render_404
129 render_404
130 end
130 end
131
131
132 # Show @project
132 # Show @project
133 def show
133 def show
134 # try to redirect to the requested menu item
134 # try to redirect to the requested menu item
135 if params[:jump] && redirect_to_project_menu_item(@project, params[:jump])
135 if params[:jump] && redirect_to_project_menu_item(@project, params[:jump])
136 return
136 return
137 end
137 end
138
138
139 @users_by_role = @project.users_by_role
139 @users_by_role = @project.users_by_role
140 @subprojects = @project.children.visible.to_a
140 @subprojects = @project.children.visible.to_a
141 @news = @project.news.limit(5).includes(:author, :project).reorder("#{News.table_name}.created_on DESC").to_a
141 @news = @project.news.limit(5).includes(:author, :project).reorder("#{News.table_name}.created_on DESC").to_a
142 @trackers = @project.rolled_up_trackers.visible
142 @trackers = @project.rolled_up_trackers.visible
143
143
144 cond = @project.project_condition(Setting.display_subprojects_issues?)
144 cond = @project.project_condition(Setting.display_subprojects_issues?)
145
145
146 @open_issues_by_tracker = Issue.visible.open.where(cond).group(:tracker).count
146 @open_issues_by_tracker = Issue.visible.open.where(cond).group(:tracker).count
147 @total_issues_by_tracker = Issue.visible.where(cond).group(:tracker).count
147 @total_issues_by_tracker = Issue.visible.where(cond).group(:tracker).count
148
148
149 if User.current.allowed_to_view_all_time_entries?(@project)
149 if User.current.allowed_to_view_all_time_entries?(@project)
150 @total_hours = TimeEntry.visible.where(cond).sum(:hours).to_f
150 @total_hours = TimeEntry.visible.where(cond).sum(:hours).to_f
151 end
151 end
152
152
153 @key = User.current.rss_key
153 @key = User.current.rss_key
154
154
155 respond_to do |format|
155 respond_to do |format|
156 format.html
156 format.html
157 format.api
157 format.api
158 end
158 end
159 end
159 end
160
160
161 def settings
161 def settings
162 @issue_custom_fields = IssueCustomField.sorted.to_a
162 @issue_custom_fields = IssueCustomField.sorted.to_a
163 @issue_category ||= IssueCategory.new
163 @issue_category ||= IssueCategory.new
164 @member ||= @project.members.new
164 @member ||= @project.members.new
165 @trackers = Tracker.sorted.to_a
165 @trackers = Tracker.sorted.to_a
166
166
167 @version_status = params[:version_status] || 'open'
167 @version_status = params[:version_status] || 'open'
168 @version_name = params[:version_name]
168 @version_name = params[:version_name]
169 @versions = @project.shared_versions.status(@version_status).like(@version_name)
169 @versions = @project.shared_versions.status(@version_status).like(@version_name)
170 @wiki ||= @project.wiki || Wiki.new(:project => @project)
170 @wiki ||= @project.wiki || Wiki.new(:project => @project)
171 end
171 end
172
172
173 def edit
173 def edit
174 end
174 end
175
175
176 def update
176 def update
177 @project.safe_attributes = params[:project]
177 @project.safe_attributes = params[:project]
178 if @project.save
178 if @project.save
179 respond_to do |format|
179 respond_to do |format|
180 format.html {
180 format.html {
181 flash[:notice] = l(:notice_successful_update)
181 flash[:notice] = l(:notice_successful_update)
182 redirect_to settings_project_path(@project)
182 redirect_to settings_project_path(@project)
183 }
183 }
184 format.api { render_api_ok }
184 format.api { render_api_ok }
185 end
185 end
186 else
186 else
187 respond_to do |format|
187 respond_to do |format|
188 format.html {
188 format.html {
189 settings
189 settings
190 render :action => 'settings'
190 render :action => 'settings'
191 }
191 }
192 format.api { render_validation_errors(@project) }
192 format.api { render_validation_errors(@project) }
193 end
193 end
194 end
194 end
195 end
195 end
196
196
197 def modules
197 def modules
198 @project.enabled_module_names = params[:enabled_module_names]
198 @project.enabled_module_names = params[:enabled_module_names]
199 flash[:notice] = l(:notice_successful_update)
199 flash[:notice] = l(:notice_successful_update)
200 redirect_to settings_project_path(@project, :tab => 'modules')
200 redirect_to settings_project_path(@project, :tab => 'modules')
201 end
201 end
202
202
203 def archive
203 def archive
204 unless @project.archive
204 unless @project.archive
205 flash[:error] = l(:error_can_not_archive_project)
205 flash[:error] = l(:error_can_not_archive_project)
206 end
206 end
207 redirect_to_referer_or admin_projects_path(:status => params[:status])
207 redirect_to_referer_or admin_projects_path(:status => params[:status])
208 end
208 end
209
209
210 def unarchive
210 def unarchive
211 unless @project.active?
211 unless @project.active?
212 @project.unarchive
212 @project.unarchive
213 end
213 end
214 redirect_to_referer_or admin_projects_path(:status => params[:status])
214 redirect_to_referer_or admin_projects_path(:status => params[:status])
215 end
215 end
216
216
217 def close
217 def close
218 @project.close
218 @project.close
219 redirect_to project_path(@project)
219 redirect_to project_path(@project)
220 end
220 end
221
221
222 def reopen
222 def reopen
223 @project.reopen
223 @project.reopen
224 redirect_to project_path(@project)
224 redirect_to project_path(@project)
225 end
225 end
226
226
227 # Delete @project
227 # Delete @project
228 def destroy
228 def destroy
229 @project_to_destroy = @project
229 @project_to_destroy = @project
230 if api_request? || params[:confirm]
230 if api_request? || params[:confirm]
231 @project_to_destroy.destroy
231 @project_to_destroy.destroy
232 respond_to do |format|
232 respond_to do |format|
233 format.html { redirect_to admin_projects_path }
233 format.html { redirect_to admin_projects_path }
234 format.api { render_api_ok }
234 format.api { render_api_ok }
235 end
235 end
236 end
236 end
237 # hide project in layout
237 # hide project in layout
238 @project = nil
238 @project = nil
239 end
239 end
240 end
240 end
General Comments 0
You need to be logged in to leave comments. Login now