Fix impediment drag and drop

pull/6827/head
Mark Maglana 14 years ago
parent b2a6131c54
commit 2f30788109
  1. 13
      app/controllers/tasks_controller.rb
  2. 2
      app/views/backlogs/show.html.erb
  3. 1
      app/views/tasks/_impediment.html.erb
  4. 1
      app/views/tasks/_task.html.erb
  5. 3
      app/views/tasks/index.html.erb
  6. 10
      assets/javascripts/impediment.js
  7. 28
      assets/javascripts/task.js
  8. 37
      assets/javascripts/taskboard.js
  9. 23
      assets/javascripts/taskboard_updater.js

@ -25,12 +25,23 @@ class TasksController < ApplicationController
def index
@sprint = Sprint.find(params[:sprint_id])
@story_ids = @sprint.stories.map{|s| s.id}
@impediment_ids = @sprint.impediments.map{|i| i.id}
@tasks = Task.find(:all,
:conditions => ["parent_id in (?) AND updated_on > ?", @story_ids, params[:after]],
:order => "updated_on ASC")
if params[:include_impediments]=='true'
@impediments = Task.find(:all,
:conditions => ["id in (?) AND updated_on > ?", @impediment_ids, params[:after]],
:order => "updated_on ASC")
end
@include_meta = true
@last_updated_conditions = "parent_id in (?) " +
(@impediments ? "OR id in (?)" : "")
@last_updated = Task.find(:first,
:conditions => ["parent_id in (?)", @story_ids],
:conditions => [@last_updated_conditions, @story_ids, @impediment_ids],
:order => "updated_on DESC")
render :action => "index", :layout => false

@ -30,7 +30,7 @@
<td<div class="label_sprint_impediments"><%= l(:label_sprint_impediments) %></div></td>
<td class="add_new">+</td>
<%- @statuses.each do |status| %>
<td class="swimlane list <%= status.is_closed? ? 'closed' : '' %>" id="impstat_<%= status.id %>">
<td class="swimlane list <%= status.is_closed? ? 'closed' : '' %>" id="impcell_<%= status.id %>">
<%= render :partial => "tasks/impediment", :collection => @sprint.impediments.select{|impediment| impediment.status_id==status.id} %>
</td>
<%- end %>

@ -11,7 +11,6 @@
<div class="meta">
<div class="story_id"><%= impediment.parent_id %></div>
<div class="status_id"><%= impediment.status_id %></div>
<div class="position"><%= impediment.position %></div>
<div class="previous"><%= impediment.higher_item.nil? ? '' : impediment.higher_item.id %></div>
</div>
<%- end %>

@ -11,7 +11,6 @@
<div class="meta">
<div class="story_id"><%= task.parent_id %></div>
<div class="status_id"><%= task.status_id %></div>
<div class="position"><%= task.position %></div>
<div class="previous"><%= task.higher_item.nil? ? '' : task.higher_item.id %></div>
</div>
<%- end %>

@ -1,4 +1,7 @@
<div>
<div class="meta" id="last_updated"><%= date_string_with_milliseconds( (@last_updated.nil? ? Time.parse(params[:after]) : @last_updated.updated_on), 0.001 ) %></div>
<%= render :partial => "task", :collection => @tasks, :locals => { :include_meta => @include_meta } %>
<%- if @impediments %>
<%= render :partial => "impediment", :collection => @impediments, :locals => { :include_meta => @include_meta }%>
<%- end %>
</div>

@ -15,20 +15,18 @@ RB.Impediment = RB.Object.create(RB.Task, {
// Associate this object with the element for later retrieval
j.data('this', this);
// Observe click events in certain fields
j.find('.editable').live('mouseup', this.triggerEdit);
j.bind('mouseup', this.handleClick);
},
// Override saveDirectives of RB.Task
saveDirectives: function(){
var j = this.$;
var prev = this.$.prev();
var cellID = j.parent('td').first().attr('id').split("_");
var sprint = $('#taskboard').data('this').getID();
var statusID = j.parent('td').first().attr('id').split("_")[1];
var data = j.find('.editor').serialize() +
"&fixed_version_id=" + sprint +
"&status_id=" + cellID[1] +
"&fixed_version_id=" + RB.constants['sprint_id'] +
"&status_id=" + statusID +
"&prev=" + (prev.length==1 ? prev.data('this').getID() : '') +
(this.isNew() ? "" : "&id=" + j.children('.id').text());
var url = RB.urlFor[(this.isNew() ? 'create_task' : 'update_task')];

@ -15,8 +15,7 @@ RB.Task = RB.Object.create(RB.Story, {
// Associate this object with the element for later retrieval
j.data('this', this);
// Observe click events in certain fields
// j.find('.editable').live('mouseup', this.triggerEdit);
j.bind('mouseup', this.handleClick);
},
afterSaveEdits: function(){
@ -24,9 +23,22 @@ RB.Task = RB.Object.create(RB.Story, {
this.$.css('background-color', c);
},
// Override RB.Story.checkSubjectLength() and do nothing
checkSubjectLength: function(){
},
edit: function(){
throw "Edit is not yet implemented";
},
handleClick: function(event){
var j = $(this);
if(!j.hasClass('editing') && !j.hasClass('dragging')){
j.data('this').edit();
}
},
handleKeyup: function(event){
var j = $(this).parents('.task').first();
var that = j.data('this');
@ -107,18 +119,6 @@ RB.Task = RB.Object.create(RB.Story, {
}
},
triggerEdit: function(event){
// Get the task since what was clicked was a field
var j = $(this).parents('.task').first();
if(!j.hasClass('editing') && !j.hasClass('dragging')){
j.data('this').edit();
// Focus on the input corresponding to the field clicked
j.find( '.' + $(event.currentTarget).attr('fieldname') + '.editor' ).focus();
}
},
unmarkSaving: function(){
this.$.removeClass('saving');
}

@ -21,7 +21,7 @@ RB.Taskboard = RB.Object.create(RB.Model, {
self.updateColWidths();
$("#col_width input").bind('keyup', function(e){ if(e.which==13) self.updateColWidths() });
// Initialize tasks
// Initialize task lists
j.find("#tasks .list").sortable({
connectWith: '#tasks .list',
placeholder: 'placeholder',
@ -37,6 +37,24 @@ RB.Taskboard = RB.Object.create(RB.Model, {
// Add handler for .add_new click
j.find('#tasks .add_new').bind('mouseup', self.handleAddNewTaskClick);
// Initialize impediment lists
j.find("#impediments .list").sortable({
connectWith: '#impediments .list',
placeholder: 'placeholder',
start: self.dragStart,
stop: self.dragStop,
update: self.dragComplete
});
// Initialize each task in the board
j.find('.impediment').each(function(index){
var task = RB.Factory.initialize(RB.Impediment, this); // 'this' refers to an element with class="impediment"
});
// Add handler for .add_new click
j.find('#impediments .add_new').bind('mouseup', self.handleAddNewImpedimentClick);
},
dragComplete: function(event, ui) {
@ -55,6 +73,11 @@ RB.Taskboard = RB.Object.create(RB.Model, {
ui.item.removeClass("dragging");
},
handleAddNewImpedimentClick: function(event){
var row = $(this).parents("tr").first();
$('#taskboard').data('this').newImpediment(row);
},
handleAddNewTaskClick: function(event){
var row = $(this).parents("tr").first();
$('#taskboard').data('this').newTask(row);
@ -69,12 +92,18 @@ RB.Taskboard = RB.Object.create(RB.Model, {
$("#col_width input").val(w);
},
newImpediment: function(row){
var impediment = $('#impediment_template').children().first().clone();
row.find(".list").first().prepend(impediment);
var o = RB.Factory.initialize(RB.Impediment, impediment);
o.edit();
},
newTask: function(row){
var task = $('#task_template').children().first().clone();
row.find(".list").first().prepend(task);
o = RB.Factory.initialize(RB.Task, task[0]);
// o.edit();
// task.find('.editor' ).first().focus();
var o = RB.Factory.initialize(RB.Task, task);
o.edit();
},
updateColWidths: function(){

@ -8,6 +8,12 @@ RB.TaskboardUpdater = RB.Object.create(RB.BoardUpdater, {
items.each(function(i, v){
self.processItem(v, false);
});
// Process impediments
var items = $(data).children('.impediment');
items.each(function(i, v){
self.processItem(v, true);
});
},
processItem: function(html, isImpediment){
@ -22,19 +28,18 @@ RB.TaskboardUpdater = RB.Object.create(RB.BoardUpdater, {
target.refresh(update);
}
// Position the item properly in the taskboard
// Place the item in the correct cell
var cell, previous, items;
if(isImpediment){
throw "Locator for impediment not yet defined";
} else {
cell = $('#' + target.$.find('.meta .story_id').text() + '_' + target.$.find('.meta .status_id').text());
cell = isImpediment ? $('#impcell_' + target.$.find('.meta .status_id').text()) : $('#' + target.$.find('.meta .story_id').text() + '_' + target.$.find('.meta .status_id').text());
cell.prepend(target.$);
}
// sort items in the cell according to position
// Sort items in the cell
items = cell.children('.task').get();
items.sort( function(a, b) { return parseInt($(a).find('.position').text()) > parseInt($(b).find('.position').text()) });
console.log(items);
items.sort( function(a, b) {
a = isNaN($(a).find('.prev').text()) ? 0 : parseInt($(a).find('.prev').text());
b = isNaN($(b).find('.prev').text()) ? 0 : parseInt($(b).find('.prev').text());
return a > b;
});
for(var ii=0; ii<items.length; ii++){
cell.append(items[ii]);
}

Loading…
Cancel
Save