You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by as...@apache.org on 2008/05/23 04:55:48 UTC
svn commit: r659384 - in /ode/sandbox/singleshot:
app/controllers/tasks_controller.rb app/models/task.rb
lib/tasks/populate.rake
Author: assaf
Date: Thu May 22 19:55:47 2008
New Revision: 659384
URL: http://svn.apache.org/viewvc?rev=659384&view=rev
Log:
Improved ranking algorithm when rendering pending task list.
Modified:
ode/sandbox/singleshot/app/controllers/tasks_controller.rb
ode/sandbox/singleshot/app/models/task.rb
ode/sandbox/singleshot/lib/tasks/populate.rake
Modified: ode/sandbox/singleshot/app/controllers/tasks_controller.rb
URL: http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/controllers/tasks_controller.rb?rev=659384&r1=659383&r2=659384&view=diff
==============================================================================
--- ode/sandbox/singleshot/app/controllers/tasks_controller.rb (original)
+++ ode/sandbox/singleshot/app/controllers/tasks_controller.rb Thu May 22 19:55:47 2008
@@ -12,7 +12,7 @@
@subtitle = 'Tasks you are performing or can claim for your own.'
@alternate = { Mime::ATOM=>formatted_tasks_url(:format=>:atom, :access_key=>authenticated.access_key),
Mime::ICS=>formatted_tasks_url(:format=>:ics, :access_key=>authenticated.access_key) }
- @tasks = Task.for_stakeholder(authenticated).pending.with_stakeholders.prioritized
+ @tasks = Task.for_stakeholder(authenticated).pending.with_stakeholders.rank_for(authenticated)
end
def show
Modified: ode/sandbox/singleshot/app/models/task.rb
URL: http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/models/task.rb?rev=659384&r1=659383&r2=659384&view=diff
==============================================================================
--- ode/sandbox/singleshot/app/models/task.rb (original)
+++ ode/sandbox/singleshot/app/models/task.rb Thu May 22 19:55:47 2008
@@ -154,15 +154,6 @@
{ :joins=>:stakeholders, :conditions=>["stakeholders.person_id=? and stakeholders.role='owner'", person.id] }
}
- named_scope :pending, :conditions=>["tasks.status IN ('ready', 'active') AND involved.role IN ('owner', 'potential')"],
- :order=>'involved.role, priority ASC, tasks.created_at' do
- def prioritized
- today = Date.today
- prioritize = lambda { |task| [task.status == 'active' ? 0 : 1, task.due_on && task.due_on <= today ? task.due_on - today : 1, task.priority] }
- self.sort { |a, b| prioritize[a] <=> prioritize[b] }
- end
- end
-
# --- Priority and ordering ---
@@ -175,27 +166,54 @@
due_on && due_on < Date.today
end
+ module Ranking
+ # Tasks are ranked by the following rules:
+ # - Tasks you're performing (owner of) always rank higher than all other tasks.
+ # - Tasks available to you rank higher than tasks not available to you
+ # - Over due tasks always rank higher than today's tasks
+ # - And today's tasks always rank higher than task with no due date
+ # - High priority tasks always rank higher than lower priority tasks
+ # - Older tasks rank higher than more recently created tasks
+ def rank_for(person)
+ today = Date.today
+ # Calculating an absolute rank value is tricky if not impossible, so instead we construct
+ # an array of values and compare these arrays against each other. To create an array we
+ # need a person's name, so we can ranked their owned tasks higher.
+ rank = lambda { |task|
+ [ person == task.owner ? 1 : 0, task.can_claim?(person) ? 1 : 0,
+ (task.due_on && task.due_on <= today) ? today - task.due_on : -1,
+ -task.priority, today - task.created_at.to_date ] }
+ self.sort { |a,b| rank[b] <=> rank[a] }
+ end
+ end
+
# --- Activities ---
has_many :activities, :include=>[:task, :person], :order=>'activities.created_at DESC', :extend=>Activity::Grouping
- # Attribute recording person who created/modified this task. Not persisted,
- # but used to log activities associated with this task.
- attr_accessor :modified_by
-
- before_save :unless=>lambda { |task| task.status == 'reserved' } do |task|
- Activity.log task, task.modified_by do |log|
- if task.changes['status']
- from, to = *task.changes['status']
- log.add task.creator, 'created' if task.creator && (from.nil? || from == 'reserved')
+ # Associate person with all modifications done on this task.
+ # This results in activities linked to the person and task when
+ # the task is saved.
+ def modified_by(person)
+ @modified_by = person
+ self
+ end
+
+ before_save :log_activities, :unless=>lambda { |task| task.status == 'reserved' }
+
+ def log_activities
+ Activity.log self, @modified_by do |log|
+ if changes['status']
+ from, to = *changes['status']
+ log.add creator, 'created' if creator && (from.nil? || from == 'reserved')
log.add 'resumed' if from == 'suspended'
case to
when 'ready'
- log.add task.changes['owner'].first, 'released' if from == 'active'
- when 'active' then log.add task.owner, 'is owner of'
+ log.add changes['owner'].first, 'released' if from == 'active'
+ when 'active' then log.add owner, 'is owner of'
when 'suspended' then log.add 'suspended'
- when 'completed' then log.add task.owner, 'completed'
+ when 'completed' then log.add owner, 'completed'
when 'cancelled' then log.add 'cancelled'
end
else
@@ -203,7 +221,8 @@
end
end
end
-
+ private :log_activities
+
# --- Completion and cancellation ---
@@ -321,4 +340,7 @@
(stakeholders.map { |sh| sh.person } + [owner, creator].compact).uniq.find { |person| token_for(person) == token }
end
+
+ named_scope :pending, :conditions=>["tasks.status IN ('ready', 'active') AND involved.role IN ('owner', 'potential')"],
+ :order=>'involved.role, priority ASC, tasks.created_at', :extend=>Ranking
end
Modified: ode/sandbox/singleshot/lib/tasks/populate.rake
URL: http://svn.apache.org/viewvc/ode/sandbox/singleshot/lib/tasks/populate.rake?rev=659384&r1=659383&r2=659384&view=diff
==============================================================================
--- ode/sandbox/singleshot/lib/tasks/populate.rake (original)
+++ ode/sandbox/singleshot/lib/tasks/populate.rake Thu May 22 19:55:47 2008
@@ -33,9 +33,8 @@
retract Task, Stakeholder, Activity
you = Person.find_by_identity(ENV['USER'])
defaults = { :title=>Faker::Lorem.sentence, :description=>Faker::Lorem.paragraph,
- :frame_url=>'http://localhost:3001/sandwich', :modified_by=>you,
- :potential_owners=>you }
- Task.create! defaults.merge(attributes || {})
+ :frame_url=>'http://localhost:3001/sandwich', :potential_owners=>you }
+ Task.new(defaults.merge(attributes || {})).modified_by(you).save!
end