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