Permalink
Browse files

(#1259) Aggregate milestone many to many assignments

  • Loading branch information...
k41n committed Jul 7, 2012
1 parent 11f9f4c commit c84256212054fec88459ad8389b978d8c238e5d4
@@ -40,4 +40,20 @@ def link_to_add_fields(name, f, association)
link_to_function(name, h("add_fields(this,\"#{association}\", \"#{escape_javascript(fields)}\")"))
end
+ def link_to_add_children_milestone_fields(name, f, association)
+ new_object = f.object.class.reflect_on_association(association).klass.new
+ fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
+ render(association.to_s.singularize + "_fields", :f=>builder)
+ end
+ link_to_function(name, h("add_children_milestone_fields(this,\"#{association}\", \"#{escape_javascript(fields)}\")"))
+ end
+
+ def link_to_add_parent_milestone_fields(name, f, association)
+ new_object = f.object.class.reflect_on_association(association).klass.new
+ fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
+ render(association.to_s.singularize + "_fields", :f=>builder)
+ end
+ link_to_function(name, h("add_parent_milestone_fields(this,\"#{association}\", \"#{escape_javascript(fields)}\")"))
+ end
+
end
View
@@ -14,9 +14,9 @@ class MilestoneInternalHelper
belongs_to :project
belongs_to :user
belongs_to :version
- belongs_to :parent_milestone, :class_name => 'Milestone', :foreign_key => :parent_milestone_id
+ #belongs_to :parent_milestone, :class_name => 'Milestone', :foreign_key => :parent_milestone_id
has_many :issues
- has_many :children, :class_name => 'Milestone', :foreign_key => :parent_milestone_id
+ #has_many :children, :class_name => 'Milestone', :foreign_key => :parent_milestone_id
belongs_to :previous_start_date_milestone, :class_name => 'Milestone', :foreign_key => :previous_start_date_milestone_id
belongs_to :previous_planned_end_date_milestone, :class_name => 'Milestone', :foreign_key => :previous_planned_end_date_milestone_id
@@ -29,7 +29,14 @@ class MilestoneInternalHelper
has_many :milestone_project_assignments
+ has_many :parent_milestone_assignments, :class_name => 'MilestoneAssignment', :foreign_key => :parent_id
+ has_many :children, :through => :parent_milestone_assignments, :as => :parent
+ has_many :child_milestone_assignments, :class_name => 'MilestoneAssignment', :foreign_key => :child_id
+ has_many :parents, :through => :child_milestone_assignments, :as => :child
+
accepts_nested_attributes_for :milestone_project_assignments, :allow_destroy => true
+ accepts_nested_attributes_for :parent_milestone_assignments, :allow_destroy => true
+ accepts_nested_attributes_for :child_milestone_assignments, :allow_destroy => true
safe_attributes 'name',
'description',
@@ -49,7 +56,9 @@ class MilestoneInternalHelper
'planned_end_date_offset',
'start_date_offset',
'previous_planned_end_date_milestone_id',
- 'previous_start_date_milestone_id'
+ 'previous_start_date_milestone_id',
+ 'parent_milestone_assignments_attributes',
+ 'child_milestone_assignments_attributes'
def self.active_for_version(version)
@@ -192,18 +201,18 @@ def <=> (a)
self.name <=> a.name
end
- def level
- return 0 if self.parent_milestone.nil? and self.kind == "aggregate"
- return 1 if self.parent_milestone.nil? and self.kind == "internal"
- return parent_milestone.level + 1
- end
+ #def level
+ # return 0 if self.parent_milestone.nil? and self.kind == "aggregate"
+ # return 1 if self.parent_milestone.nil? and self.kind == "internal"
+ # return parent_milestone.level + 1
+ #end
def aggregate?
self.kind == 'aggregate'
end
def orphaned?
- self.parent_milestone.nil?
+ self.parents.internal.empty?
end
def opened?
@@ -0,0 +1,6 @@
+class MilestoneAssignment < ActiveRecord::Base
+ unloadable
+
+ belongs_to :parent, :class_name=>"Milestone", :foreign_key => :parent_id
+ belongs_to :child, :class_name=>"Milestone", :foreign_key => :child_id
+end
@@ -0,0 +1,5 @@
+<p class='fields'>
+ <%= f.select :parent_id, options_for_select(Milestone.internal.collect{|x| [x.name, x.id]}, f.object.parent_id) %>
+ <%= f.hidden_field :_destroy %>
+ <%= link_to_function l(:button_delete), "remove_fields(this)" %>
+</p>
@@ -7,13 +7,23 @@
<p><%= f.select :kind, Milestone::MILESTONE_KINDS.collect {|s| [l("milestone_kind_#{s}"), s]}, {}, {:onchange => 'milestone_type_changed()'} %></p>
<p><%= f.select :project_id, options_for_select(Project.all.collect {|x| [x.name, x.id]}, @project.id), {}, {:onchange => "new_milestone_project_selected()"} %></p>
- <div id="internal_milestone_form_part">
+ <div id="internal_milestone_form_part" style="<%= "display:none" if @milestone.kind == 'aggregate' %>">
<div id="subproject_placeholder" style="display:none">
<p><%= f.select :subproject_id, {}, {:onchange => "new_milestone_subproject_selected()"} %></p>
</div>
<div id="version_placeholder">
<p><%= f.select :version_id, @project.versions.collect {|x| [x.name, x.id]}, {}, {:onchange => "milestone_version_changed('#{@project.id}')"} %></p>
</div>
+ <%= link_to_add_parent_milestone_fields(t(:assign_milestone), f, :child_milestone_assignments ) %>
+ <% f.fields_for :child_milestone_assignments do |assignment| %>
+ <%= render :partial => "child_milestone_assignment_fields", :locals=>{:f=>assignment} unless assignment.object.nil? %>
+ <% end %>
+ </div>
+ <div id="aggregate_milestone_form_part" style="<%= "display:none" if @milestone.kind == 'internal' %>">
+ <%= link_to_add_children_milestone_fields(t(:add_assigned_milestone), f, :parent_milestone_assignments ) %>
+ <% f.fields_for :parent_milestone_assignments do |assignment| %>
+ <%= render :partial => "parent_milestone_assignment_fields", :locals=>{:f=>assignment} unless assignment.object.nil? %>
+ <% end %>
</div>
<p><%= f.select :status, options_for_select(Milestone::MILESTONE_STATUSES.collect {|s| [l("version_status_#{s}"), s]}, @milestone.status) %></p>
@@ -67,8 +77,6 @@
<%= render :partial => "milestone_project_assignment_fields", :locals=>{:f=>assignment} %>
<% end %>
</div>
- <% @milestones = @project.milestones.aggregate.reject{|x| x.id == @milestone.id} %>
- <%= render :partial =>"milestones/available_milestones" %>
<p><%= f.select :user_id, @project.users.collect {|u| [u.name, u.id]} %></p>
@@ -0,0 +1,5 @@
+<p class='fields'>
+ <%= f.select :child_id, options_for_select(Milestone.aggregate.collect{|x| [x.name, x.id]}, f.object.child_id) %>
+ <%= f.hidden_field :_destroy %>
+ <%= link_to_function l(:button_delete), "remove_fields(this)" %>
+</p>
@@ -1,12 +1,13 @@
+<% level = 0 if level.nil? %>
<div>
- <% prefix = (sidebar_milestone.level > 0 ? ('&nbsp;' * 2 * sidebar_milestone.level + '&#187; ') : '') %>
+ <% prefix = (level > 0 ? ('&nbsp;' * 2 * level + '&#187; ') : '') %>
<%= prefix %>
<%= link_to sidebar_milestone.name, milestone_path(sidebar_milestone) %>
<% unless sidebar_milestone.children.empty? %>
<% if params[:completed_milestones] %>
- <%= render :partial => "milestones/sidebar_milestone", :collection => sidebar_milestone.children %>
+ <%= render :partial => "milestones/sidebar_milestone", :collection => sidebar_milestone.children, :locals => {:level => level+1} %>
<% else %>
- <%= render :partial => "milestones/sidebar_milestone", :collection => sidebar_milestone.children.opened %>
+ <%= render :partial => "milestones/sidebar_milestone", :collection => sidebar_milestone.children.opened, :locals => {:level => level+1} %>
<% end %>
<% end %>
</div>
@@ -4,10 +4,12 @@ function milestone_type_changed()
if (selected == 'internal')
{
$('internal_milestone_form_part').show();
+ $('aggregate_milestone_form_part').hide();
}
else
{
$('internal_milestone_form_part').hide();
+ $('aggregate_milestone_form_part').show();
}
}
@@ -187,6 +189,20 @@ function add_fields(link, association, content)
$('assigned_projects_placeholder').insert({bottom: content.replace(regexp, new_id)});
}
+function add_children_milestone_fields(link, association, content)
+{
+ var new_id = new Date().getTime();
+ var regexp = new RegExp("new_"+association, "g");
+ $('aggregate_milestone_form_part').insert({bottom: content.replace(regexp, new_id)});
+}
+
+function add_parent_milestone_fields(link, association, content)
+{
+ var new_id = new Date().getTime();
+ var regexp = new RegExp("new_"+association, "g");
+ $('internal_milestone_form_part').insert({bottom: content.replace(regexp, new_id)});
+}
+
function remove_fields(link)
{
$(link).previous("input[type=hidden]").value = "1";
View
@@ -43,4 +43,7 @@ en:
add_assigned_project: Add assigned project
internal: internal
aggregate: aggregate
- owner: owner
+ owner: owner
+ add_assigned_milestone: Assign milestone
+ field_child: Child milestone
+ assign_milestone: Assign to
View
@@ -43,4 +43,7 @@ ru:
add_assigned_project: Добавить связанный проект
internal: внутренний
aggregate: агрегатный
- owner: владелец
+ owner: владелец
+ add_assigned_milestone: Привязать этап
+ field_child: Дочерний этап
+ assign_milestone: Привязать к этапу
@@ -0,0 +1,12 @@
+class CreateMilestoneAssignments < ActiveRecord::Migration
+ def self.up
+ create_table :milestone_assignments do |t|
+ t.references :parent
+ t.references :child
+ end
+ end
+
+ def self.down
+ drop_table :milestone_assignments
+ end
+end
@@ -0,0 +1,5 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+one:
+ id: 1
+two:
+ id: 2
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class MilestoneAssignmentTest < ActiveSupport::TestCase
+ fixtures :milestone_assignments
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end

0 comments on commit c842562

Please sign in to comment.