##// END OF EJS Templates
Added observers to watch model objects for mail delivery instead of calling Mailer....
Added observers to watch model objects for mail delivery instead of calling Mailer. * Added an IssueObserver to watch when Issues are created * Added a JournalObserver to watch when Journals are created (Issue updates) * Added a NewsObserver for News items. * Added a DocumentObserver for Document notifications. * Setup IssuesController#new to use the IssueObserver. * Setup IssuesController#edit to use the IssueObserver. * Setup IssuesController#bulk_edit to use the JournalObserver. * Removed the Mailer call in Changeset#scan_commit_for_issue_ids, the JournalObserver will handle it. * Removed Mailer calls in MailHandler in favor of the Observers. #2659 git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2637 e93f8b46-1217-0410-a6f0-8f06a7374b81

File last commit:

r2548:b4be8849c0de
r2548:b4be8849c0de
Show More
issues_controller.rb
492 lines | 22.9 KiB | text/x-ruby | RubyLexer
/ app / controllers / issues_controller.rb
Jean-Philippe Lang
Adds support for free ticket filtering and custom queries on Calendar....
r1796 # Redmine - project management software
# Copyright (C) 2006-2008 Jean-Philippe Lang
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 #
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class IssuesController < ApplicationController
Jean-Philippe Lang
Added a 'New issue' link in the main menu (accesskey 7)....
r1067 menu_item :new_issue, :only => :new
Jean-Philippe Lang
AttachmentsController now handles attachments deletion....
r2114 before_filter :find_issue, :only => [:show, :edit, :reply]
Jean-Philippe Lang
Issue list now supports bulk edit/move/delete (#563, #607). For now, issues from different projects can not be bulk edited/moved/deleted at once....
r1116 before_filter :find_issues, :only => [:bulk_edit, :move, :destroy]
Jean-Philippe Lang
Cross-project gantt and calendar (#1157)....
r2086 before_filter :find_project, :only => [:new, :update_form, :preview]
before_filter :authorize, :except => [:index, :changes, :gantt, :calendar, :preview, :update_form, :context_menu]
before_filter :find_optional_project, :only => [:index, :changes, :gantt, :calendar]
Jean-Philippe Lang
ProjectsController#list_issues, #export_issues_csv and #export_issues_pdf merged into IssuesController#index...
r874 accept_key_auth :index, :changes
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330
Jean-Philippe Lang
Administrators can edit issue notes....
r1091 helper :journals
Jean-Philippe Lang
Fixed version field on issue view page now links to the corresponding version in the roadmap....
r559 helper :projects
include ProjectsHelper
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 helper :custom_fields
include CustomFieldsHelper
Jean-Philippe Lang
Issue relations first commit (not thoroughly tested). 4 kinds of relation are available:...
r503 helper :issue_relations
include IssueRelationsHelper
Jean-Philippe Lang
Added watchers for message boards (watchers controller modified to support any watchable model)....
r527 helper :watchers
include WatchersHelper
Jean-Philippe Lang
Attachments can now be added to wiki pages (original patch by Pavol Murin). Only authorized users can add/delete attachments....
r538 helper :attachments
Jean-Philippe Lang
Added a cross-project issue list. It displays the issues of all the projects visible by the user....
r673 include AttachmentsHelper
helper :queries
helper :sort
include SortHelper
Jean-Philippe Lang
ProjectsController#list_issues, #export_issues_csv and #export_issues_pdf merged into IssuesController#index...
r874 include IssuesHelper
Jean-Philippe Lang
Addq "please select" to activity select box if no activity is set as default (#937)....
r1588 helper :timelog
Jean-Philippe Lang
Move PDF stuff to a single helper....
r2224 include Redmine::Export::PDF
Jean-Philippe Lang
data locking for issues...
r21
Jean-Philippe Lang
Added a cross-project issue list. It displays the issues of all the projects visible by the user....
r673 def index
retrieve_query
Jean-Philippe Lang
Ability to save "sort order" in custom queries (#2899)....
r2504 sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria)
Jean-Philippe Lang
Validates sort_key and sort_order params (#2378)....
r2169 sort_update({'id' => "#{Issue.table_name}.id"}.merge(@query.columns.inject({}) {|h, c| h[c.name.to_s] = c.sortable; h}))
Jean-Philippe Lang
Added a cross-project issue list. It displays the issues of all the projects visible by the user....
r673 if @query.valid?
Jean-Philippe Lang
Display links to Atom feeds (closes #496, #750)....
r1171 limit = per_page_option
respond_to do |format|
format.html { }
format.atom { }
format.csv { limit = Setting.issues_export_limit.to_i }
format.pdf { limit = Setting.issues_export_limit.to_i }
end
Jean-Philippe Lang
ProjectsController#list_issues, #export_issues_csv and #export_issues_pdf merged into IssuesController#index...
r874 @issue_count = Issue.count(:include => [:status, :project], :conditions => @query.statement)
@issue_pages = Paginator.new self, @issue_count, limit, params['page']
Jean-Philippe Lang
Added a cross-project issue list. It displays the issues of all the projects visible by the user....
r673 @issues = Issue.find :all, :order => sort_clause,
Jean-Philippe Lang
'fixed version' field can now be displayed on the issue list....
r901 :include => [ :assigned_to, :status, :tracker, :project, :priority, :category, :fixed_version ],
Jean-Philippe Lang
Added a cross-project issue list. It displays the issues of all the projects visible by the user....
r673 :conditions => @query.statement,
Jean-Philippe Lang
ProjectsController#list_issues, #export_issues_csv and #export_issues_pdf merged into IssuesController#index...
r874 :limit => limit,
:offset => @issue_pages.current.offset
respond_to do |format|
format.html { render :template => 'issues/index.rhtml', :layout => !request.xhr? }
Jean-Philippe Lang
Adds project name to issues feed title (#1323)....
r1627 format.atom { render_feed(@issues, :title => "#{@project || Setting.app_title}: #{l(:label_issue_plural)}") }
Jean-Philippe Lang
ProjectsController#list_issues, #export_issues_csv and #export_issues_pdf merged into IssuesController#index...
r874 format.csv { send_data(issues_to_csv(@issues, @project).read, :type => 'text/csv; header=present', :filename => 'export.csv') }
Jean-Philippe Lang
Move PDF stuff to a single helper....
r2224 format.pdf { send_data(issues_to_pdf(@issues, @project), :type => 'application/pdf', :filename => 'export.pdf') }
Jean-Philippe Lang
ProjectsController#list_issues, #export_issues_csv and #export_issues_pdf merged into IssuesController#index...
r874 end
else
# Send html if the query is not valid
render(:template => 'issues/index.rhtml', :layout => !request.xhr?)
Jean-Philippe Lang
Added a cross-project issue list. It displays the issues of all the projects visible by the user....
r673 end
Jean-Philippe Lang
Queries can be marked as 'For all projects'. Such queries will be available on all projects and on the global issue list (#897, closes #671)....
r1296 rescue ActiveRecord::RecordNotFound
render_404
Jean-Philippe Lang
ProjectsController#list_issues, #export_issues_csv and #export_issues_pdf merged into IssuesController#index...
r874 end
def changes
retrieve_query
Jean-Philippe Lang
Validates sort_key and sort_order params (#2378)....
r2169 sort_init 'id', 'desc'
sort_update({'id' => "#{Issue.table_name}.id"}.merge(@query.columns.inject({}) {|h, c| h[c.name.to_s] = c.sortable; h}))
Jean-Philippe Lang
ProjectsController#list_issues, #export_issues_csv and #export_issues_pdf merged into IssuesController#index...
r874 if @query.valid?
Jean-Philippe Lang
Display links to Atom feeds (closes #496, #750)....
r1171 @journals = Journal.find :all, :include => [ :details, :user, {:issue => [:project, :author, :tracker, :status]} ],
Jean-Philippe Lang
ProjectsController#list_issues, #export_issues_csv and #export_issues_pdf merged into IssuesController#index...
r874 :conditions => @query.statement,
:limit => 25,
:order => "#{Journal.table_name}.created_on DESC"
Jean-Philippe Lang
Added atom feed on the new cross-project issue list....
r675 end
Jean-Philippe Lang
ProjectsController#list_issues, #export_issues_csv and #export_issues_pdf merged into IssuesController#index...
r874 @title = (@project ? @project.name : Setting.app_title) + ": " + (@query.new_record? ? l(:label_changes_details) : @query.name)
render :layout => false, :content_type => 'application/atom+xml'
Jean-Philippe Lang
Queries can be marked as 'For all projects'. Such queries will be available on all projects and on the global issue list (#897, closes #671)....
r1296 rescue ActiveRecord::RecordNotFound
render_404
Jean-Philippe Lang
Added a cross-project issue list. It displays the issues of all the projects visible by the user....
r673 end
Jean-Philippe Lang
data locking for issues...
r21 def show
Jean-Philippe Lang
Issue history is now 'oldest first' sorted....
r627 @journals = @issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC")
Jean-Philippe Lang
Add a user preference to choose how comments/replies are displayed: in chronological or reverse chronological order (#589, #776)....
r1183 @journals.each_with_index {|j,i| j.indice = i+1}
@journals.reverse! if User.current.wants_comments_in_reverse_order?
Jean-Philippe Lang
Sort changesets in the same order as comments on the issue details view (#1546)....
r2455 @changesets = @issue.changesets
@changesets.reverse! if User.current.wants_comments_in_reverse_order?
Jean-Philippe Lang
Merged IssuesController #edit and #update into a single actions....
r1115 @allowed_statuses = @issue.new_statuses_allowed_to(User.current)
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
Jean-Philippe Lang
Replaces Enumeration.get_values and Enumeration.default with named scopes....
r2411 @priorities = Enumeration.priorities
Jean-Philippe Lang
Fixed: IssueController#edit doesn't set default Activity as default (#1302)....
r1447 @time_entry = TimeEntry.new
Jean-Philippe Lang
ProjectsController#list_issues, #export_issues_csv and #export_issues_pdf merged into IssuesController#index...
r874 respond_to do |format|
format.html { render :template => 'issues/show.rhtml' }
Jean-Philippe Lang
Display links to Atom feeds (closes #496, #750)....
r1171 format.atom { render :action => 'changes', :layout => false, :content_type => 'application/atom+xml' }
Jean-Philippe Lang
Move PDF stuff to a single helper....
r2224 format.pdf { send_data(issue_to_pdf(@issue), :type => 'application/pdf', :filename => "#{@project.identifier}-#{@issue.id}.pdf") }
Jean-Philippe Lang
Merged IssuesController#export_pdf into IssuesController#show....
r799 end
Jean-Philippe Lang
data locking for issues...
r21 end
Jean-Philippe Lang
Initial commit...
r2
Jean-Philippe Lang
ProjectsController#add_issue moved to IssuesController#new....
r1066 # Add a new issue
# The new issue will be created from an existing one if copy_from parameter is given
def new
Jean-Philippe Lang
Custom fields refactoring: most of code moved from controllers to models (using new module ActsAsCustomizable)....
r1578 @issue = Issue.new
@issue.copy_from(params[:copy_from]) if params[:copy_from]
Jean-Philippe Lang
ProjectsController#add_issue moved to IssuesController#new....
r1066 @issue.project = @project
Jean-Philippe Lang
Fixed: issues always created with default tracker (#1553)....
r1596 # Tracker must be set before custom field values
@issue.tracker ||= @project.trackers.find((params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] || :first)
Jean-Philippe Lang
ProjectsController#add_issue moved to IssuesController#new....
r1066 if @issue.tracker.nil?
Jean-Philippe Lang
Fixed that some error messages were not displayed (#2866)....
r2474 render_error 'No tracker is associated to this project. Please check the Project settings.'
Jean-Philippe Lang
ProjectsController#add_issue moved to IssuesController#new....
r1066 return
end
Jean-Philippe Lang
Adds watchers selection on new issue form (#398). Permission 'add issue watchers' required....
r2162 if params[:issue].is_a?(Hash)
@issue.attributes = params[:issue]
@issue.watcher_user_ids = params[:issue]['watcher_user_ids'] if User.current.allowed_to?(:add_issue_watchers, @project)
end
Jean-Philippe Lang
Custom fields refactoring: most of code moved from controllers to models (using new module ActsAsCustomizable)....
r1578 @issue.author = User.current
Jean-Philippe Lang
ProjectsController#add_issue moved to IssuesController#new....
r1066
default_status = IssueStatus.default
unless default_status
Jean-Philippe Lang
Fixed that some error messages were not displayed (#2866)....
r2474 render_error 'No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").'
Jean-Philippe Lang
ProjectsController#add_issue moved to IssuesController#new....
r1066 return
end
@issue.status = default_status
Jean-Philippe Lang
Fixed: Multiple "new" statuses in filing new ticket (closes #751)....
r1165 @allowed_statuses = ([default_status] + default_status.find_new_statuses_allowed_to(User.current.role_for_project(@project), @issue.tracker)).uniq
Jean-Philippe Lang
ProjectsController#add_issue moved to IssuesController#new....
r1066
if request.get? || request.xhr?
@issue.start_date ||= Date.today
else
requested_status = IssueStatus.find_by_id(params[:issue][:status_id])
# Check that the user is allowed to apply the requested status
@issue.status = (@allowed_statuses.include? requested_status) ? requested_status : default_status
if @issue.save
attach_files(@issue, params[:attachments])
flash[:notice] = l(:notice_successful_create)
Eric Davis
Added two new plugin hooks to IssuesController:...
r2259 call_hook(:controller_issues_new_after_save, { :params => params, :issue => @issue})
Jean-Philippe Lang
Adds a 'Create and continue' button on the new issue form, that will create the issue and display the form again (#2523)....
r2263 redirect_to(params[:continue] ? { :action => 'new', :tracker_id => @issue.tracker } :
{ :action => 'show', :id => @issue })
Jean-Philippe Lang
ProjectsController#add_issue moved to IssuesController#new....
r1066 return
end
end
Jean-Philippe Lang
Replaces Enumeration.get_values and Enumeration.default with named scopes....
r2411 @priorities = Enumeration.priorities
Jean-Philippe Lang
ProjectsController#add_issue moved to IssuesController#new....
r1066 render :layout => !request.xhr?
end
Jean-Philippe Lang
Merged IssuesController #edit and #update into a single actions....
r1115 # Attributes that can be updated on workflow transition (without :edit permission)
# TODO: make it configurable (at least per role)
UPDATABLE_ATTRS_ON_TRANSITION = %w(status_id assigned_to_id fixed_version_id done_ratio) unless const_defined?(:UPDATABLE_ATTRS_ON_TRANSITION)
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 def edit
Jean-Philippe Lang
Merged IssuesController #edit and #update into a single actions....
r1115 @allowed_statuses = @issue.new_statuses_allowed_to(User.current)
Jean-Philippe Lang
Replaces Enumeration.get_values and Enumeration.default with named scopes....
r2411 @priorities = Enumeration.priorities
Jean-Philippe Lang
Merged IssuesController #edit and #update into a single actions....
r1115 @edit_allowed = User.current.allowed_to?(:edit_issues, @project)
Jean-Philippe Lang
Adds custom fields on time entries (#772)....
r1672 @time_entry = TimeEntry.new
Jean-Philippe Lang
Issue list now supports bulk edit/move/delete (#563, #607). For now, issues from different projects can not be bulk edited/moved/deleted at once....
r1116
@notes = params[:notes]
journal = @issue.init_journal(User.current, @notes)
# User can change issue attributes only if he has :edit permission or if a workflow transition is allowed
if (@edit_allowed || !@allowed_statuses.empty?) && params[:issue]
attrs = params[:issue].dup
attrs.delete_if {|k,v| !UPDATABLE_ATTRS_ON_TRANSITION.include?(k) } unless @edit_allowed
attrs.delete(:status_id) unless @allowed_statuses.detect {|s| s.id.to_s == attrs[:status_id].to_s}
@issue.attributes = attrs
end
Jean-Philippe Lang
Custom fields refactoring: most of code moved from controllers to models (using new module ActsAsCustomizable)....
r1578 if request.post?
Jean-Philippe Lang
Fixed: Logtime info lost when there's an error updating an issue (#1400)....
r1521 @time_entry = TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today)
@time_entry.attributes = params[:time_entry]
Jean-Philippe Lang
Merged IssuesController change_status and add_note actions....
r1030 attachments = attach_files(@issue, params[:attachments])
attachments.each {|a| journal.details << JournalDetail.new(:property => 'attachment', :prop_key => a.id, :value => a.filename)}
Eric Davis
Added :controller_issues_edit_before_save hook...
r2084
call_hook(:controller_issues_edit_before_save, { :params => params, :issue => @issue, :time_entry => @time_entry, :journal => journal})
Jean-Philippe Lang
Do not silently ignore timelog validation failure on issue edit....
r1589 if (@time_entry.hours.nil? || @time_entry.valid?) && @issue.save
Jean-Philippe Lang
Merged IssuesController change_status and add_note actions....
r1030 # Log spend time
Jean-Philippe Lang
Timelog is ignored when updating an issue if user is admin but not a project member (#2717)....
r2402 if User.current.allowed_to?(:log_time, @project)
Jean-Philippe Lang
Merged IssuesController change_status and add_note actions....
r1030 @time_entry.save
end
if !journal.new_record?
# Only send notification if something was actually changed
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 flash[:notice] = l(:notice_successful_update)
end
Eric Davis
Added two new plugin hooks to IssuesController:...
r2259 call_hook(:controller_issues_edit_after_save, { :params => params, :issue => @issue, :time_entry => @time_entry, :journal => journal})
Jean-Philippe Lang
Merged IssuesController change_status and add_note actions....
r1030 redirect_to(params[:back_to] || {:action => 'show', :id => @issue})
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 end
Jean-Philippe Lang
Merged IssuesController change_status and add_note actions....
r1030 end
rescue ActiveRecord::StaleObjectError
# Optimistic locking exception
flash.now[:error] = l(:notice_locking_conflict)
Jean-Philippe Lang
data locking for issues...
r21 end
Jean-Philippe Lang
Adds a Reply link to each issue note (#739). Reply is pre-filled with the quoted note....
r1466 def reply
journal = Journal.find(params[:journal_id]) if params[:journal_id]
if journal
user = journal.user
text = journal.notes
else
user = @issue.author
text = @issue.description
end
Jean-Philippe Lang
Fixed: Reply/Quote Function Newline Issue in Internet Explorer (#1362)....
r1487 content = "#{ll(Setting.default_language, :text_user_wrote, user)}\\n> "
content << text.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]').gsub('"', '\"').gsub(/(\r?\n|\r\n?)/, "\\n> ") + "\\n\\n"
Jean-Philippe Lang
Adds a Reply link to each issue note (#739). Reply is pre-filled with the quoted note....
r1466 render(:update) { |page|
Jean-Philippe Lang
Fixed: Reply/Quote Function Newline Issue in Internet Explorer (#1362)....
r1487 page.<< "$('notes').value = \"#{content}\";"
Jean-Philippe Lang
Adds a Reply link to each issue note (#739). Reply is pre-filled with the quoted note....
r1466 page.show 'update'
page << "Form.Element.focus('notes');"
page << "Element.scrollTo('update');"
page << "$('notes').scrollTop = $('notes').scrollHeight - $('notes').clientHeight;"
}
end
Jean-Philippe Lang
Issue list now supports bulk edit/move/delete (#563, #607). For now, issues from different projects can not be bulk edited/moved/deleted at once....
r1116 # Bulk edit a set of issues
def bulk_edit
if request.post?
status = params[:status_id].blank? ? nil : IssueStatus.find_by_id(params[:status_id])
priority = params[:priority_id].blank? ? nil : Enumeration.find_by_id(params[:priority_id])
Jean-Philippe Lang
Fixed: when bulk editing, setting "Assigned to" to "nobody" causes an sql error with Postgresql (#935)....
r1279 assigned_to = (params[:assigned_to_id].blank? || params[:assigned_to_id] == 'none') ? nil : User.find_by_id(params[:assigned_to_id])
category = (params[:category_id].blank? || params[:category_id] == 'none') ? nil : @project.issue_categories.find_by_id(params[:category_id])
fixed_version = (params[:fixed_version_id].blank? || params[:fixed_version_id] == 'none') ? nil : @project.versions.find_by_id(params[:fixed_version_id])
Jean-Philippe Lang
Ability to bulk edit custom fields of type 'list' (#461)....
r2314 custom_field_values = params[:custom_field_values] ? params[:custom_field_values].reject {|k,v| v.blank?} : nil
Jean-Philippe Lang
Issue list now supports bulk edit/move/delete (#563, #607). For now, issues from different projects can not be bulk edited/moved/deleted at once....
r1116
unsaved_issue_ids = []
@issues.each do |issue|
journal = issue.init_journal(User.current, params[:notes])
issue.priority = priority if priority
issue.assigned_to = assigned_to if assigned_to || params[:assigned_to_id] == 'none'
Jean-Philippe Lang
Fixed: when bulk editing, setting "Assigned to" to "nobody" causes an sql error with Postgresql (#935)....
r1279 issue.category = category if category || params[:category_id] == 'none'
issue.fixed_version = fixed_version if fixed_version || params[:fixed_version_id] == 'none'
Jean-Philippe Lang
Issue list now supports bulk edit/move/delete (#563, #607). For now, issues from different projects can not be bulk edited/moved/deleted at once....
r1116 issue.start_date = params[:start_date] unless params[:start_date].blank?
issue.due_date = params[:due_date] unless params[:due_date].blank?
issue.done_ratio = params[:done_ratio] unless params[:done_ratio].blank?
Jean-Philippe Lang
Ability to bulk edit custom fields of type 'list' (#461)....
r2314 issue.custom_field_values = custom_field_values if custom_field_values && !custom_field_values.empty?
Jean-Philippe Lang
Merged hooks branch @ r1785 into trunk....
r1785 call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue })
Jean-Philippe Lang
Issue list now supports bulk edit/move/delete (#563, #607). For now, issues from different projects can not be bulk edited/moved/deleted at once....
r1116 # Don't save any change to the issue if the user is not authorized to apply the requested status
Eric Davis
Added observers to watch model objects for mail delivery instead of calling Mailer....
r2548 unless (status.nil? || (issue.status.new_status_allowed_to?(status, current_role, issue.tracker) && issue.status = status)) && issue.save
Jean-Philippe Lang
Issue list now supports bulk edit/move/delete (#563, #607). For now, issues from different projects can not be bulk edited/moved/deleted at once....
r1116 # Keep unsaved issue ids to display them in flash error
unsaved_issue_ids << issue.id
end
end
if unsaved_issue_ids.empty?
flash[:notice] = l(:notice_successful_update) unless @issues.empty?
else
Jean-Philippe Lang
Merged Rails 2.2 branch. Redmine now requires Rails 2.2.2....
r2430 flash[:error] = l(:notice_failed_to_save_issues, :count => unsaved_issue_ids.size,
:total => @issues.size,
:ids => '#' + unsaved_issue_ids.join(', #'))
Jean-Philippe Lang
Issue list now supports bulk edit/move/delete (#563, #607). For now, issues from different projects can not be bulk edited/moved/deleted at once....
r1116 end
Jean-Philippe Lang
One-click bulk edition using the issue list context menu within the same project (#1770)....
r1764 redirect_to(params[:back_to] || {:controller => 'issues', :action => 'index', :project_id => @project})
Jean-Philippe Lang
Issue list now supports bulk edit/move/delete (#563, #607). For now, issues from different projects can not be bulk edited/moved/deleted at once....
r1116 return
end
# Find potential statuses the user could be allowed to switch issues to
@available_statuses = Workflow.find(:all, :include => :new_status,
Jean-Philippe Lang
Fixed: Status list on bulk edit form does not follow normal sequence (#1956)....
r1911 :conditions => {:role_id => current_role.id}).collect(&:new_status).compact.uniq.sort
Jean-Philippe Lang
Ability to bulk edit custom fields of type 'list' (#461)....
r2314 @custom_fields = @project.issue_custom_fields.select {|f| f.field_format == 'list'}
Jean-Philippe Lang
Issue list now supports bulk edit/move/delete (#563, #607). For now, issues from different projects can not be bulk edited/moved/deleted at once....
r1116 end
def move
@allowed_projects = []
# find projects to which the user is allowed to move the issue
if User.current.admin?
# admin is allowed to move issues to any active (visible) project
Jean-Philippe Lang
Render the project list as a tree on Move form....
r2313 @allowed_projects = Project.find(:all, :conditions => Project.visible_by(User.current))
Jean-Philippe Lang
Issue list now supports bulk edit/move/delete (#563, #607). For now, issues from different projects can not be bulk edited/moved/deleted at once....
r1116 else
User.current.memberships.each {|m| @allowed_projects << m.project if m.role.allowed_to?(:move_issues)}
end
@target_project = @allowed_projects.detect {|p| p.id.to_s == params[:new_project_id]} if params[:new_project_id]
@target_project ||= @project
@trackers = @target_project.trackers
if request.post?
new_tracker = params[:new_tracker_id].blank? ? nil : @target_project.trackers.find_by_id(params[:new_tracker_id])
unsaved_issue_ids = []
@issues.each do |issue|
Jean-Philippe Lang
Track project and tracker changes in issue history....
r1551 issue.init_journal(User.current)
Jean-Philippe Lang
Adds ability to bulk copy issues (#1847)....
r2311 unsaved_issue_ids << issue.id unless issue.move_to(@target_project, new_tracker, params[:copy_options])
Jean-Philippe Lang
Issue list now supports bulk edit/move/delete (#563, #607). For now, issues from different projects can not be bulk edited/moved/deleted at once....
r1116 end
if unsaved_issue_ids.empty?
flash[:notice] = l(:notice_successful_update) unless @issues.empty?
else
Jean-Philippe Lang
Merged Rails 2.2 branch. Redmine now requires Rails 2.2.2....
r2430 flash[:error] = l(:notice_failed_to_save_issues, :count => unsaved_issue_ids.size,
:total => @issues.size,
:ids => '#' + unsaved_issue_ids.join(', #'))
Jean-Philippe Lang
Issue list now supports bulk edit/move/delete (#563, #607). For now, issues from different projects can not be bulk edited/moved/deleted at once....
r1116 end
redirect_to :controller => 'issues', :action => 'index', :project_id => @project
return
end
render :layout => false if request.xhr?
end
Jean-Philippe Lang
data locking for issues...
r21 def destroy
Jean-Philippe Lang
Let the user choose when deleting issues with reported hours (closes #734, #71):...
r1168 @hours = TimeEntry.sum(:hours, :conditions => ['issue_id IN (?)', @issues]).to_f
if @hours > 0
case params[:todo]
when 'destroy'
# nothing to do
when 'nullify'
TimeEntry.update_all('issue_id = NULL', ['issue_id IN (?)', @issues])
when 'reassign'
reassign_to = @project.issues.find_by_id(params[:reassign_to_id])
if reassign_to.nil?
flash.now[:error] = l(:error_issue_not_found_in_project)
return
else
TimeEntry.update_all("issue_id = #{reassign_to.id}", ['issue_id IN (?)', @issues])
end
else
# display the destroy form
return
end
end
Jean-Philippe Lang
Issue list now supports bulk edit/move/delete (#563, #607). For now, issues from different projects can not be bulk edited/moved/deleted at once....
r1116 @issues.each(&:destroy)
Jean-Philippe Lang
ProjectsController#list_issues, #export_issues_csv and #export_issues_pdf merged into IssuesController#index...
r874 redirect_to :action => 'index', :project_id => @project
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 end
Jean-Philippe Lang
Added AJAX based context menu on the project issue list that provide shortcuts for editing, re-assigning, changing the status or the priority, moving or deleting an issue....
r859
Jean-Philippe Lang
Adds support for free ticket filtering and custom queries on Gantt chart....
r1795 def gantt
@gantt = Redmine::Helpers::Gantt.new(params)
retrieve_query
if @query.valid?
events = []
# Issues that have start and due dates
events += Issue.find(:all,
:order => "start_date, due_date",
:include => [:tracker, :status, :assigned_to, :priority, :project],
:conditions => ["(#{@query.statement}) AND (((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?) or (start_date<? and due_date>?)) and start_date is not null and due_date is not null)", @gantt.date_from, @gantt.date_to, @gantt.date_from, @gantt.date_to, @gantt.date_from, @gantt.date_to]
)
# Issues that don't have a due date but that are assigned to a version with a date
events += Issue.find(:all,
:order => "start_date, effective_date",
:include => [:tracker, :status, :assigned_to, :priority, :project, :fixed_version],
:conditions => ["(#{@query.statement}) AND (((start_date>=? and start_date<=?) or (effective_date>=? and effective_date<=?) or (start_date<? and effective_date>?)) and start_date is not null and due_date is null and effective_date is not null)", @gantt.date_from, @gantt.date_to, @gantt.date_from, @gantt.date_to, @gantt.date_from, @gantt.date_to]
)
Jean-Philippe Lang
Changes versions retrieval on gantt chart....
r1797 # Versions
events += Version.find(:all, :include => :project,
:conditions => ["(#{@query.project_statement}) AND effective_date BETWEEN ? AND ?", @gantt.date_from, @gantt.date_to])
Jean-Philippe Lang
Adds support for free ticket filtering and custom queries on Gantt chart....
r1795 @gantt.events = events
end
respond_to do |format|
format.html { render :template => "issues/gantt.rhtml", :layout => !request.xhr? }
Jean-Philippe Lang
Fixed an error when downloading gantt png at global level....
r2330 format.png { send_data(@gantt.to_image, :disposition => 'inline', :type => 'image/png', :filename => "#{@project.nil? ? '' : "#{@project.identifier}-" }gantt.png") } if @gantt.respond_to?('to_image')
Jean-Philippe Lang
Move PDF stuff to a single helper....
r2224 format.pdf { send_data(gantt_to_pdf(@gantt, @project), :type => 'application/pdf', :filename => "#{@project.nil? ? '' : "#{@project.identifier}-" }gantt.pdf") }
Jean-Philippe Lang
Adds support for free ticket filtering and custom queries on Gantt chart....
r1795 end
end
Jean-Philippe Lang
Adds support for free ticket filtering and custom queries on Calendar....
r1796 def calendar
if params[:year] and params[:year].to_i > 1900
@year = params[:year].to_i
if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13
@month = params[:month].to_i
end
end
@year ||= Date.today.year
@month ||= Date.today.month
@calendar = Redmine::Helpers::Calendar.new(Date.civil(@year, @month, 1), current_language, :month)
retrieve_query
if @query.valid?
events = []
events += Issue.find(:all,
:include => [:tracker, :status, :assigned_to, :priority, :project],
:conditions => ["(#{@query.statement}) AND ((start_date BETWEEN ? AND ?) OR (due_date BETWEEN ? AND ?))", @calendar.startdt, @calendar.enddt, @calendar.startdt, @calendar.enddt]
)
events += Version.find(:all, :include => :project,
:conditions => ["(#{@query.project_statement}) AND effective_date BETWEEN ? AND ?", @calendar.startdt, @calendar.enddt])
@calendar.events = events
end
render :layout => false if request.xhr?
end
Jean-Philippe Lang
Added AJAX based context menu on the project issue list that provide shortcuts for editing, re-assigning, changing the status or the priority, moving or deleting an issue....
r859 def context_menu
Jean-Philippe Lang
Issue list now supports bulk edit/move/delete (#563, #607). For now, issues from different projects can not be bulk edited/moved/deleted at once....
r1116 @issues = Issue.find_all_by_id(params[:ids], :include => :project)
if (@issues.size == 1)
@issue = @issues.first
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
end
projects = @issues.collect(&:project).compact.uniq
@project = projects.first if projects.size == 1
@can = {:edit => (@project && User.current.allowed_to?(:edit_issues, @project)),
Jean-Philippe Lang
Fixes r1672....
r1656 :log_time => (@project && User.current.allowed_to?(:log_time, @project)),
Jean-Philippe Lang
One-click bulk edition using the issue list context menu within the same project (#1770)....
r1764 :update => (@project && (User.current.allowed_to?(:edit_issues, @project) || (User.current.allowed_to?(:change_status, @project) && @allowed_statuses && !@allowed_statuses.empty?))),
Jean-Philippe Lang
Issue list now supports bulk edit/move/delete (#563, #607). For now, issues from different projects can not be bulk edited/moved/deleted at once....
r1116 :move => (@project && User.current.allowed_to?(:move_issues, @project)),
:copy => (@issue && @project.trackers.include?(@issue.tracker) && User.current.allowed_to?(:add_issues, @project)),
:delete => (@project && User.current.allowed_to?(:delete_issues, @project))
}
Jean-Philippe Lang
One-click bulk edition using the issue list context menu within the same project (#1770)....
r1764 if @project
@assignables = @project.assignable_users
@assignables << @issue.assigned_to if @issue && @issue.assigned_to && !@assignables.include?(@issue.assigned_to)
end
Jean-Philippe Lang
Replaces Enumeration.get_values and Enumeration.default with named scopes....
r2411 @priorities = Enumeration.priorities.reverse
Jean-Philippe Lang
Added AJAX based context menu on the project issue list that provide shortcuts for editing, re-assigning, changing the status or the priority, moving or deleting an issue....
r859 @statuses = IssueStatus.find(:all, :order => 'position')
Jean-Philippe Lang
Issue list now supports bulk edit/move/delete (#563, #607). For now, issues from different projects can not be bulk edited/moved/deleted at once....
r1116 @back = request.env['HTTP_REFERER']
Jean-Philippe Lang
Added AJAX based context menu on the project issue list that provide shortcuts for editing, re-assigning, changing the status or the priority, moving or deleting an issue....
r859 render :layout => false
end
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330
Jean-Philippe Lang
ProjectsController#add_issue moved to IssuesController#new....
r1066 def update_form
@issue = Issue.new(params[:issue])
render :action => :new, :layout => false
end
Jean-Philippe Lang
Added preview on add/edit issue form....
r801 def preview
Jean-Philippe Lang
Fixed: trying to preview a new issue raises an exception (closes #984)....
r1341 @issue = @project.issues.find_by_id(params[:id]) unless params[:id].blank?
Jean-Philippe Lang
Fixed: preview fails when updating an issue (broken by r1322). Patch #1027....
r1326 @attachements = @issue.attachments if @issue
Jean-Philippe Lang
Merged IssuesController #edit and #update into a single actions....
r1115 @text = params[:notes] || (params[:issue] ? params[:issue][:description] : nil)
Jean-Philippe Lang
Added preview on add/edit issue form....
r801 render :partial => 'common/preview'
end
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 private
Jean-Philippe Lang
ProjectsController#add_issue moved to IssuesController#new....
r1066 def find_issue
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 @issue = Issue.find(params[:id], :include => [:project, :tracker, :status, :author, :priority, :category])
@project = @issue.project
rescue ActiveRecord::RecordNotFound
render_404
Jean-Philippe Lang
Added a cross-project issue list. It displays the issues of all the projects visible by the user....
r673 end
Jean-Philippe Lang
Issue list now supports bulk edit/move/delete (#563, #607). For now, issues from different projects can not be bulk edited/moved/deleted at once....
r1116 # Filter for bulk operations
def find_issues
@issues = Issue.find_all_by_id(params[:id] || params[:ids])
raise ActiveRecord::RecordNotFound if @issues.empty?
projects = @issues.collect(&:project).compact.uniq
if projects.size == 1
@project = projects.first
else
# TODO: let users bulk edit/move/destroy issues from different projects
render_error 'Can not bulk edit/move/destroy issues from different projects' and return false
end
rescue ActiveRecord::RecordNotFound
render_404
end
Jean-Philippe Lang
ProjectsController#add_issue moved to IssuesController#new....
r1066 def find_project
@project = Project.find(params[:project_id])
rescue ActiveRecord::RecordNotFound
render_404
end
Jean-Philippe Lang
ProjectsController#list_issues, #export_issues_csv and #export_issues_pdf merged into IssuesController#index...
r874 def find_optional_project
Jean-Philippe Lang
Cross-project gantt and calendar (#1157)....
r2086 @project = Project.find(params[:project_id]) unless params[:project_id].blank?
allowed = User.current.allowed_to?({:controller => params[:controller], :action => params[:action]}, @project, :global => true)
allowed ? true : deny_access
Jean-Philippe Lang
ProjectsController#list_issues, #export_issues_csv and #export_issues_pdf merged into IssuesController#index...
r874 rescue ActiveRecord::RecordNotFound
render_404
end
Jean-Philippe Lang
Added a cross-project issue list. It displays the issues of all the projects visible by the user....
r673 # Retrieve query from session or build a new query
def retrieve_query
Jean-Philippe Lang
Fixed an error on issue feeds....
r1092 if !params[:query_id].blank?
Jean-Philippe Lang
Queries can be marked as 'For all projects'. Such queries will be available on all projects and on the global issue list (#897, closes #671)....
r1296 cond = "project_id IS NULL"
cond << " OR project_id = #{@project.id}" if @project
@query = Query.find(params[:query_id], :conditions => cond)
@query.project = @project
Jean-Philippe Lang
Do not store query object in session but id or filters only. This allows to use Rails 2.0 cookie based sessions....
r1014 session[:query] = {:id => @query.id, :project_id => @query.project_id}
Jean-Philippe Lang
Ability to save "sort order" in custom queries (#2899)....
r2504 sort_clear
Jean-Philippe Lang
ProjectsController#list_issues, #export_issues_csv and #export_issues_pdf merged into IssuesController#index...
r874 else
Jean-Philippe Lang
Do not store query object in session but id or filters only. This allows to use Rails 2.0 cookie based sessions....
r1014 if params[:set_filter] || session[:query].nil? || session[:query][:project_id] != (@project ? @project.id : nil)
Jean-Philippe Lang
ProjectsController#list_issues, #export_issues_csv and #export_issues_pdf merged into IssuesController#index...
r874 # Give it a name, required to be valid
Jean-Philippe Lang
Anonymous users can now be allowed to create, edit, comment issues, comment news and post messages in the forums....
r906 @query = Query.new(:name => "_")
Jean-Philippe Lang
ProjectsController#list_issues, #export_issues_csv and #export_issues_pdf merged into IssuesController#index...
r874 @query.project = @project
if params[:fields] and params[:fields].is_a? Array
params[:fields].each do |field|
@query.add_filter(field, params[:operators][field], params[:values][field])
end
else
@query.available_filters.keys.each do |field|
@query.add_short_filter(field, params[field]) if params[field]
end
Jean-Philippe Lang
Added a cross-project issue list. It displays the issues of all the projects visible by the user....
r673 end
Jean-Philippe Lang
Do not store query object in session but id or filters only. This allows to use Rails 2.0 cookie based sessions....
r1014 session[:query] = {:project_id => @query.project_id, :filters => @query.filters}
Jean-Philippe Lang
Added a cross-project issue list. It displays the issues of all the projects visible by the user....
r673 else
Jean-Philippe Lang
Do not store query object in session but id or filters only. This allows to use Rails 2.0 cookie based sessions....
r1014 @query = Query.find_by_id(session[:query][:id]) if session[:query][:id]
@query ||= Query.new(:name => "_", :project => @project, :filters => session[:query][:filters])
Jean-Philippe Lang
Issue list shows all tickets when going back to a global query inside a project (closes #1055)....
r1337 @query.project = @project
Jean-Philippe Lang
Added a cross-project issue list. It displays the issues of all the projects visible by the user....
r673 end
end
end
Jean-Philippe Lang
Initial commit...
r2 end