ChiliProject is not maintained anymore. Please be advised that there will be no more updates.
We do not recommend that you setup new ChiliProject instances and we urge all existing users to migrate their data to a maintained system, e.g. Redmine. We will provide a migration script later. In the meantime, you can use the instructions by Christian Daehn.
category-share.diff
b/app/controllers/issue_categories_controller.rb | ||
---|---|---|
25 | 25 |
|
26 | 26 |
verify :method => :post, :only => :destroy |
27 | 27 | |
28 |
helper :projects |
|
29 | ||
28 | 30 |
def new |
29 | 31 |
@category = @project.issue_categories.build(params[:category]) |
30 | 32 |
if request.post? |
b/app/helpers/projects_helper.rb | ||
---|---|---|
105 | 105 |
sharing = 'none' unless Version::VERSION_SHARINGS.include?(sharing) |
106 | 106 |
l("label_version_sharing_#{sharing}") |
107 | 107 |
end |
108 | ||
109 |
def format_category_sharing(sharing) |
|
110 |
sharing = 'none' unless IssueCategory::SHARINGS.include?(sharing) |
|
111 |
l("label_version_sharing_#{sharing}") |
|
112 |
end |
|
108 | 113 |
end |
b/app/models/issue.rb | ||
---|---|---|
143 | 143 |
unless new_project.shared_versions.include?(issue.fixed_version) |
144 | 144 |
issue.fixed_version = nil |
145 | 145 |
end |
146 |
# Keep the category if it's still valid in the new_project |
|
147 |
unless new_project.shared_categories.include?(issue.category) |
|
148 |
issue.category = nil |
|
149 |
end |
|
146 | 150 |
issue.project = new_project |
147 | 151 |
if issue.parent && issue.parent.project_id != issue.project_id |
148 | 152 |
issue.parent_issue_id = nil |
... | ... | |
313 | 317 |
errors.add_to_base I18n.t(:error_can_not_reopen_issue_on_closed_version) |
314 | 318 |
end |
315 | 319 |
end |
320 | ||
321 |
if category |
|
322 |
if !assignable_categories.include?(category) |
|
323 |
errors.add :category_id, :inclusion |
|
324 |
end |
|
325 |
end |
|
316 | 326 |
|
317 | 327 |
# Checks that the issue can not be added/moved to a disabled tracker |
318 | 328 |
if project && (tracker_id_changed? || project_id_changed?) |
... | ... | |
414 | 424 |
def assignable_versions |
415 | 425 |
@assignable_versions ||= (project.shared_versions.open + [Version.find_by_id(fixed_version_id_was)]).compact.uniq.sort |
416 | 426 |
end |
427 | ||
428 |
# Categories that the issue can be assigned to |
|
429 |
def assignable_categories |
|
430 |
@assignable_categories ||= (project.shared_categories + [IssueCategory.find_by_id(category_id_was)]).compact.uniq.sort |
|
431 |
end |
|
417 | 432 |
|
418 | 433 |
# Returns true if this issue is blocked by another issue that is still open |
419 | 434 |
def blocked? |
... | ... | |
573 | 588 |
# Update issues assigned to the version |
574 | 589 |
update_versions(["#{Issue.table_name}.fixed_version_id = ?", version.id]) |
575 | 590 |
end |
591 | ||
592 |
# Unassigns issues from +category+ if it's no longer shared with issue's project |
|
593 |
def self.update_categories_from_sharing_change(category) |
|
594 |
# Update issues assigned to the category |
|
595 |
update_categories(["#{Issue.table_name}.category_id = ?", category.id]) |
|
596 |
end |
|
576 | 597 |
|
577 | 598 |
# Unassigns issues from versions that are no longer shared |
578 | 599 |
# after +project+ was moved |
... | ... | |
776 | 797 |
end |
777 | 798 |
end |
778 | 799 |
end |
800 | ||
801 |
# Update issues so their categories are not pointing to a |
|
802 |
# fixed_version that is not shared with the issue's project |
|
803 |
def self.update_categories(conditions=nil) |
|
804 |
# Only need to update issues with a fixed_version from |
|
805 |
# a different project and that is not systemwide shared |
|
806 |
Issue.all(:conditions => merge_conditions("#{Issue.table_name}.category_id IS NOT NULL" + |
|
807 |
" AND #{Issue.table_name}.project_id <> #{IssueCategory.table_name}.project_id" + |
|
808 |
" AND #{IssueCategory.table_name}.sharing <> 'system'", |
|
809 |
conditions), |
|
810 |
:include => [:project, :category] |
|
811 |
).each do |issue| |
|
812 |
next if issue.project.nil? || issue.category.nil? |
|
813 |
unless issue.project.shared_categories.include?(issue.category) |
|
814 |
issue.init_journal(User.current) |
|
815 |
issue.category = nil |
|
816 |
issue.save |
|
817 |
end |
|
818 |
end |
|
819 |
end |
|
779 | 820 |
|
780 | 821 |
# Callback on attachment deletion |
781 | 822 |
def attachment_removed(obj) |
b/app/models/issue_category.rb | ||
---|---|---|
16 | 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
17 | 17 | |
18 | 18 |
class IssueCategory < ActiveRecord::Base |
19 |
after_update :update_issues_from_sharing_change |
|
19 | 20 |
belongs_to :project |
20 | 21 |
belongs_to :assigned_to, :class_name => 'User', :foreign_key => 'assigned_to_id' |
21 | 22 |
has_many :issues, :foreign_key => 'category_id', :dependent => :nullify |
23 | ||
24 |
SHARINGS = %w(none descendants hierarchy tree system) |
|
22 | 25 |
|
23 | 26 |
validates_presence_of :name |
24 | 27 |
validates_uniqueness_of :name, :scope => [:project_id] |
25 | 28 |
validates_length_of :name, :maximum => 30 |
29 |
validates_inclusion_of :sharing, :in => SHARINGS |
|
26 | 30 |
|
27 | 31 |
alias :destroy_without_reassign :destroy |
28 | 32 |
|
... | ... | |
40 | 44 |
end |
41 | 45 |
|
42 | 46 |
def to_s; name end |
47 | ||
48 |
# Returns the sharings that +user+ can set the category to |
|
49 |
def allowed_sharings(user = User.current) |
|
50 |
SHARINGS.select do |s| |
|
51 |
if sharing == s |
|
52 |
true |
|
53 |
else |
|
54 |
case s |
|
55 |
when 'system' |
|
56 |
# Only admin users can set a systemwide sharing |
|
57 |
user.admin? |
|
58 |
when 'hierarchy', 'tree' |
|
59 |
# Only users allowed to manage versions of the root project can |
|
60 |
# set sharing to hierarchy or tree |
|
61 |
project.nil? || user.allowed_to?(:manage_versions, project.root) |
|
62 |
else |
|
63 |
true |
|
64 |
end |
|
65 |
end |
|
66 |
end |
|
67 |
end |
|
68 | ||
69 |
# Update the issue's fixed versions. Used if a version's sharing changes. |
|
70 |
def update_issues_from_sharing_change |
|
71 |
if sharing_changed? |
|
72 |
if SHARINGS.index(sharing_was).nil? || |
|
73 |
SHARINGS.index(sharing).nil? || |
|
74 |
SHARINGS.index(sharing_was) > SHARINGS.index(sharing) |
|
75 |
Issue.update_categories_from_sharing_change self |
|
76 |
end |
|
77 |
end |
|
78 |
end |
|
43 | 79 |
end |
b/app/models/project.rb | ||
---|---|---|
384 | 384 |
"))") |
385 | 385 |
end |
386 | 386 | |
387 |
# Returns a scope of the Versions used by the project |
|
388 |
def shared_categories |
|
389 |
@shared_categories ||= |
|
390 |
IssueCategory.find(:all, :include => :project, |
|
391 |
:conditions => "#{Project.table_name}.id = #{id}" + |
|
392 |
" OR (#{Project.table_name}.status = #{Project::STATUS_ACTIVE} AND (" + |
|
393 |
" #{IssueCategory.table_name}.sharing = 'system'" + |
|
394 |
" OR (#{Project.table_name}.lft >= #{root.lft} AND #{Project.table_name}.rgt <= #{root.rgt} AND #{IssueCategory.table_name}.sharing = 'tree')" + |
|
395 |
" OR (#{Project.table_name}.lft < #{lft} AND #{Project.table_name}.rgt > #{rgt} AND #{IssueCategory.table_name}.sharing IN ('hierarchy', 'descendants'))" + |
|
396 |
" OR (#{Project.table_name}.lft > #{lft} AND #{Project.table_name}.rgt < #{rgt} AND #{IssueCategory.table_name}.sharing = 'hierarchy')" + |
|
397 |
"))") |
|
398 |
end |
|
399 | ||
387 | 400 |
# Returns a hash of project users grouped by role |
388 | 401 |
def users_by_role |
389 | 402 |
members.find(:all, :include => [:user, :roles]).inject({}) do |h, m| |
b/app/views/issue_categories/_form.rhtml | ||
---|---|---|
3 | 3 |
<div class="box"> |
4 | 4 |
<p><%= f.text_field :name, :size => 30, :required => true %></p> |
5 | 5 |
<p><%= f.select :assigned_to_id, @project.users.sort.collect{|u| [u.name, u.id]}, :include_blank => true %></p> |
6 |
<p><%= f.select :sharing, @category.allowed_sharings.collect{|c| [format_category_sharing(c), c]} %></p> |
|
6 | 7 |
</div> |
b/app/views/issues/_attributes.rhtml | ||
---|---|---|
9 | 9 | |
10 | 10 |
<p><%= f.select :priority_id, (@priorities.collect {|p| [p.name, p.id]}), {:required => true}, :disabled => !@issue.leaf? %></p> |
11 | 11 |
<p><%= f.select :assigned_to_id, (@issue.assignable_users.collect {|m| [m.name, m.id]}), :include_blank => true %></p> |
12 |
<% unless @project.issue_categories.empty? %>
|
|
13 |
<p><%= f.select :category_id, (@project.issue_categories.collect {|c| [c.name, c.id]}), :include_blank => true %>
|
|
12 |
<% unless @issue.assignable_categories.empty? %>
|
|
13 |
<p><%= f.select :category_id, (@issue.assignable_categories.collect {|c| [c.name, c.id]}), :include_blank => true %>
|
|
14 | 14 |
<%= prompt_to_remote(image_tag('add.png', :style => 'vertical-align: middle;'), |
15 | 15 |
l(:label_issue_category_new), |
16 | 16 |
'category[name]', |
b/db/migrate/20110216000000_add_issue_category_sharing.rb | ||
---|---|---|
1 |
class AddIssueCategorySharing < ActiveRecord::Migration |
|
2 |
def self.up |
|
3 |
add_column :issue_categories, :sharing, :string, :default => 'none', :null => false |
|
4 |
add_index :issue_categories, :sharing |
|
5 |
end |
|
6 | ||
7 |
def self.down |
|
8 |
remove_column :issue_categories, :sharing |
|
9 |
end |
|
10 |
end |