Author: assaf
Date: Mon Jun  2 21:52:44 2008
New Revision: 662645

URL: http://svn.apache.org/viewvc?rev=662645&view=rev
Log:
Activity list now broken across dates and includes time.  Activity list in task 
is similar.
Activity no longer requires person, but always gets modified_by.
Completed list similar to activity list.
Task view shows status (completed, suspended, etc), priority and task title.
Significant improvement to tabular task list.

Added:
    ode/sandbox/singleshot/app/helpers/activity_helper.rb
    ode/sandbox/singleshot/app/views/activities/_activities.html.erb
Removed:
    ode/sandbox/singleshot/app/views/tasks/_task.html.erb
    ode/sandbox/singleshot/app/views/tasks/by_day.html.erb
Modified:
    ode/sandbox/singleshot/app/controllers/activities_controller.rb
    ode/sandbox/singleshot/app/controllers/tasks_controller.rb
    ode/sandbox/singleshot/app/helpers/application_helper.rb
    ode/sandbox/singleshot/app/helpers/task_helper.rb
    ode/sandbox/singleshot/app/models/activity.rb
    ode/sandbox/singleshot/app/models/task.rb
    ode/sandbox/singleshot/app/views/activities/index.atom.builder
    ode/sandbox/singleshot/app/views/activities/index.html.erb
    ode/sandbox/singleshot/app/views/activities/index.ics.ical
    ode/sandbox/singleshot/app/views/tasks/completed.html.erb
    ode/sandbox/singleshot/app/views/tasks/following.html.erb
    ode/sandbox/singleshot/app/views/tasks/index.html.erb
    ode/sandbox/singleshot/app/views/tasks/show.html.erb
    ode/sandbox/singleshot/db/migrate/20080506015153_create_activities.rb
    ode/sandbox/singleshot/db/schema.rb
    ode/sandbox/singleshot/public/javascripts/application.js
    ode/sandbox/singleshot/public/stylesheets/default.css

Modified: ode/sandbox/singleshot/app/controllers/activities_controller.rb
URL: 
http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/controllers/activities_controller.rb?rev=662645&r1=662644&r2=662645&view=diff
==============================================================================
--- ode/sandbox/singleshot/app/controllers/activities_controller.rb (original)
+++ ode/sandbox/singleshot/app/controllers/activities_controller.rb Mon Jun  2 
21:52:44 2008
@@ -12,24 +12,21 @@
     dates = day ? day..day + 1.day : Date.today - 3.day..Date.today + 1.day
     @activities = @activities.for_dates(dates)
     respond_to do |want|
-      want.html { @days = @activities.group_by_day }
+      want.html
       want.atom
       want.ics
     end
   end
 
   def show
-    @task = Task.for_stakeholder(authenticated).find(params[:id])
+    @task = Task.for_stakeholder(authenticated).find(params[:id], 
:include=>:activities)
+    @activities = @task.activities
     @title = "Activities - [EMAIL PROTECTED]"
     @subtitle = "Track all activities in the task [EMAIL PROTECTED]"
     @alternate = { Mime::ATOM=>formatted_activity_url(@task, :atom, 
:access_key=>authenticated.access_key),
                    Mime::ICS=>formatted_activity_url(@task, :ics, 
:access_key=>authenticated.access_key) }
-    @activities = @task.activities
     respond_to do |want|
-      want.html do
-        @days = @activities.group_by_day
-        render :action=>'index'
-      end
+      want.html { render :action=>'index' }
       want.atom { render :action=>'index' }
       want.ics  { render :action=>'index' }
     end

Modified: ode/sandbox/singleshot/app/controllers/tasks_controller.rb
URL: 
http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/controllers/tasks_controller.rb?rev=662645&r1=662644&r2=662645&view=diff
==============================================================================
--- ode/sandbox/singleshot/app/controllers/tasks_controller.rb (original)
+++ ode/sandbox/singleshot/app/controllers/tasks_controller.rb Mon Jun  2 
21:52:44 2008
@@ -26,7 +26,7 @@
                    Mime::ICS=>formatted_completed_tasks_url(:format=>:ics, 
:access_key=>authenticated.access_key) }
     @tasks = Task.completed.for_stakeholder(authenticated).with_stakeholders
     respond_to do |wants|
-      wants.html { @days = @tasks.group_by { |task| task.updated_at.to_date } }
+      wants.html
       # TODO: wants.xml
       # TODO: wants.json
       wants.atom { render :action=>'index' }
@@ -49,6 +49,7 @@
   end
 
   def show
+    @title = @task.title
     @alternate = { Mime::ICS=>formatted_tasks_url(:format=>:ics, 
:access_key=>authenticated.access_key) }
     respond_to do |wants|
       wants.html { render :layout=>'head' }

Added: ode/sandbox/singleshot/app/helpers/activity_helper.rb
URL: 
http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/helpers/activity_helper.rb?rev=662645&view=auto
==============================================================================
--- ode/sandbox/singleshot/app/helpers/activity_helper.rb (added)
+++ ode/sandbox/singleshot/app/helpers/activity_helper.rb Mon Jun  2 21:52:44 
2008
@@ -0,0 +1,14 @@
+module ActivityHelper
+
+  def activity_to_text(activity)
+    activity.person ? "#{activity.person.fullname} #{activity.action} 
#{activity.task.title}" :
+      "#{activity.action.capitalize} #{activity.task.title}"
+  end
+
+  def activity_to_html(activity, options = {})
+    title = link_to(h(activity.task.title), task_url(activity.task), 
options[:task])
+    activity.person ? "#{link_to_person activity.person, options[:person]} 
#{activity.action} #{title}" :
+      "#{activity.action.capitalize} #{title}"
+  end
+
+end

Modified: ode/sandbox/singleshot/app/helpers/application_helper.rb
URL: 
http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/helpers/application_helper.rb?rev=662645&r1=662644&r2=662645&view=diff
==============================================================================
--- ode/sandbox/singleshot/app/helpers/application_helper.rb (original)
+++ ode/sandbox/singleshot/app/helpers/application_helper.rb Mon Jun  2 
21:52:44 2008
@@ -5,14 +5,9 @@
   # (or profile, if unspecified) as the reference.
   def link_to_person(person, *args)
     options = args.extract_options!
-    if person == authenticated  
-      content_tag('span', 'you')
-    elsif person.url
-      options.update :rel=>args.first if args.first
-      link_to(h(person.fullname), person.url, options.merge(:title=>"See 
#{h(person.fullname)}'s profile"))
-    else
-      content_tag('span', fullname)
-    end
+    options[:class] = "#{options[:class]} fn url"
+    person.url ? link_to(h(person.fullname), person.url, 
options.merge(:title=>"See #{person.fullname}'s profile")) :
+      content_tag('span', fullname, options)
   end
 
   # Returns Person object for currently authenticated user.
@@ -34,8 +29,8 @@
     end
   end
 
-  def relative_time(time)
-    case age = Time.now - time
+  def age(time, ago = true)
+    text = case age = Time.now - time
     when 0...2.minute
       '1 minute'
     when 2.minute...1.hour
@@ -49,18 +44,64 @@
     when 2.day...1.month
       '%d days' % (age / 1.day)
     when 1.month...2.month
-      'about 1 month'
+      '1 month'
     else
       '%d months' % (age / 1.month) if age > 0
     end
+    text && ago ? "#{text} ago" : text
+  end
+
+  def relative_time(time)
+    case age = Time.now - time
+    when 0...2.minute
+      'this minute'
+    when 2.minute...1.hour
+      '%d minutes ago' % (age / 1.minute)
+    when 1.hour...2.hour
+      'this hour'
+    when 2.hour...1.day
+      '%d hours ago' % (age / 1.hour)
+    when 1.day...2.day
+      'yesterday'
+    when 2.day...1.month
+      '%d days ago' % (age / 1.day)
+    when 1.month...2.month
+      'about 1 month'
+    else
+      '%d months ago' % (age / 1.month) if age > 0
+    end
   end
 
   def abbr_date(date, text, options = {})
-    content_tag 'abbr', text, 
options.merge(:title=>date.to_date.strftime('%Y%m%d'))
+    content_tag 'abbr', text, 
options.merge(:title=>date.to_date.strftime('%Y-%m-%d'))
   end
 
   def abbr_time(time, text, options = {})
-    content_tag 'abbr', text, 
options.merge(:title=>time.strftime('%Y%m%dT%H:%M:%S'))
+    content_tag 'abbr', text, options.merge(:title=>time.iso8601)
+  end
+
+  def group_by_dates(activities, attr = :updated_at)
+    activities.inject([]) do |groups, activity|
+      date, today = activity.send(attr).to_date, Date.today
+      group = if date == today
+        'today'
+      elsif date == today.yesterday
+        'yesterday'
+      elsif date.cweek == today.cweek
+        date.strftime('%A')
+      elsif date.year == today.year
+        date.strftime('%b %d')
+      else
+        date.strftime('%b %d, %Y')
+      end
+      previous = groups.last
+      if previous && previous.first == group
+        previous.last << activity
+        groups
+      else
+        groups.push([group, [activity]])
+      end
+    end
   end
 
 end

Modified: ode/sandbox/singleshot/app/helpers/task_helper.rb
URL: 
http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/helpers/task_helper.rb?rev=662645&r1=662644&r2=662645&view=diff
==============================================================================
--- ode/sandbox/singleshot/app/helpers/task_helper.rb (original)
+++ ode/sandbox/singleshot/app/helpers/task_helper.rb Mon Jun  2 21:52:44 2008
@@ -8,11 +8,22 @@
   end
 
   def task_vitals(task)
-    vitals = ['Created ' + abbr_time(task.created_at, 
relative_date(task.created_at), :class=>'published')]
-    vitals.first << ' by ' + link_to_person(task.creator, :creator) if 
task.creator
-    vitals << (task.status == 'completed' ? "completed by " : "assigned to ") 
+ link_to_person(task.owner, :owner) if task.owner
-    vitals << "due #{relative_date(task.due_on)}" if task.due_on
-    vitals.to_sentence
+    case task.status
+    when 'ready', 'active'
+      vitals = [ 'Created ' + abbr_time(task.created_at, 
relative_time(task.created_at), :class=>'published') ]
+      vitals.first << ' by ' + link_to_person(task.creator, :creator) if 
task.creator
+      vitals << 'assigned to ' + link_to_person(task.owner, :owner) if 
task.owner
+      vitals << 'high priority' if task.high_priority?
+      vitals << 'due ' + abbr_date(task.due_on, relative_date(task.due_on)) if 
task.due_on
+      vitals.to_sentence
+    when 'active'
+    when 'suspended'
+      return "Suspended"
+    when 'completed'
+      "Completed on #{task.updated_at.to_date.to_s(:long)} by #{link_to_person 
task.owner, :owner}"
+    when 'cancelled'
+      "Cancelled on #{task.updated_at.to_date.to_s(:long)}"
+    end
   end
 
   def task_frame(task)

Modified: ode/sandbox/singleshot/app/models/activity.rb
URL: 
http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/models/activity.rb?rev=662645&r1=662644&r2=662645&view=diff
==============================================================================
--- ode/sandbox/singleshot/app/models/activity.rb (original)
+++ ode/sandbox/singleshot/app/models/activity.rb Mon Jun  2 21:52:44 2008
@@ -14,42 +14,15 @@
 
   belongs_to :person
   belongs_to :task
+  validates_presence_of :task_id
 
   attr_readonly :person, :task, :action
 
-  module GroupingMethods
-    def group_by_day
-      self.inject([]) do |days, activity|
-        created = activity.created_at.to_date
-        day = days.last if days.last && days.last.first == created
-        days << (day = [created, []]) unless day
-        day.last << activity
-        days
-      end
-    end
-  end
-
-  named_scope :for_stakeholder,
-    lambda { |person| { :joins=>'JOIN stakeholders AS involved ON 
involved.task_id=tasks.id',
+  named_scope :for_stakeholder, lambda { |person|
+    { :joins=>'JOIN stakeholders AS involved ON involved.task_id=tasks.id',
       :conditions=>["involved.person_id=? AND involved.role != 'excluded'", 
person.id],
-      :include=>[:task, :person], :order=>'activities.created_at DESC', 
:extend=>GroupingMethods } }
-  named_scope :for_dates,
-    lambda { |dates| { :conditions=>{ :created_at=>dates } } }
-
-  class << self
-
-    def log(task, modified_by)
-      activities = Hash.new
-      class << activities ; self ;end.send :define_method, :add do |*args|
-        person = Person === args.first ? args.shift : modified_by
-        self[person] = Array(self[person]).push(*args) if person
-      end
-      yield activities
-      activities.each do |person, actions|
-        task.activities.build :person=>person, :action=>actions.to_sentence
-      end
-    end
-
-  end
+      :include=>[:task, :person], :order=>'activities.created_at DESC' } }
+  named_scope :for_dates, lambda { |dates|
+    { :conditions=>{ :created_at=>dates } } }
 
 end

Modified: ode/sandbox/singleshot/app/models/task.rb
URL: 
http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/models/task.rb?rev=662645&r1=662644&r2=662645&view=diff
==============================================================================
--- ode/sandbox/singleshot/app/models/task.rb (original)
+++ ode/sandbox/singleshot/app/models/task.rb Mon Jun  2 21:52:44 2008
@@ -199,7 +199,7 @@
 
   # --- Activities ---
  
-  has_many :activities, :include=>[:task, :person], 
:order=>'activities.created_at DESC', :extend=>Activity::GroupingMethods
+  has_many :activities, :include=>[:task, :person], 
:order=>'activities.created_at DESC'
 
   # Associate person with all modifications done on this task.
   # This results in activities linked to the person and task when
@@ -209,27 +209,38 @@
     self
   end
 
-  before_save :log_activities, :unless=>lambda { |task| task.status == 
'reserved' }
-  def log_activities
-    Activity.log self, @modified_by do |log|
-      if status_changed?
-        from, to = status_change
-        log.add creator, 'created' if creator && (from.nil? || from == 
'reserved')
-        log.add 'resumed' if from == 'suspended'
+  before_save :unless=>lambda { |task| task.status == 'reserved' } do |task|
+    task.log_activities do |log|
+      if task.status_changed?
+        from, to = task.status_change
+        log.add task.creator, 'created' if from.nil? || from == 'reserved'
         case to
         when 'ready'
-          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 owner, 'completed'
-        when 'cancelled' then log.add 'cancelled'
+          log.add nil, 'resumed' if from == 'suspended'
+          log.add task.changes['owner'].first, 'released' if from == 'active'
+        when 'active'
+          log.add nil, 'resumed' if from == 'suspended'
+          log.add task.owner, 'is owner of'
+        when 'suspended' then log.add nil, 'suspended'
+        when 'completed' then log.add task.owner, 'completed'
+        when 'cancelled' then log.add nil, 'cancelled'
         end
       else
-        log.add 'modified'
+        log.add nil, 'modified'
       end
     end
   end
-  private :log_activities
+
+  def log_activities
+    log = Hash.new
+    def log.add(person, action)
+      self[person] = Array(self[person]).push(action)
+    end
+    yield log
+    log.each do |person, actions|
+      activities.build :person=>person || @modified_by, 
:action=>actions.to_sentence
+    end
+  end
   
 
   # --- Completion and cancellation ---
@@ -365,7 +376,7 @@
       :order=>'tasks.updated_at DESC' } }
 
   named_scope :following, lambda { |end_date|
-    { :conditions=>["involved.role != 'excluded' AND tasks.updated_at >= ?", 
end_date || Date.today - 7.days],
+    { :conditions=>["tasks.updated_at >= ?", end_date || Date.today - 7.days],
       :order=>'tasks.updated_at DESC' } }
 
   named_scope :visible, :conditions=>["tasks.status != 'reserved'"]

Added: ode/sandbox/singleshot/app/views/activities/_activities.html.erb
URL: 
http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/views/activities/_activities.html.erb?rev=662645&view=auto
==============================================================================
--- ode/sandbox/singleshot/app/views/activities/_activities.html.erb (added)
+++ ode/sandbox/singleshot/app/views/activities/_activities.html.erb Mon Jun  2 
21:52:44 2008
@@ -0,0 +1,9 @@
+<ol class='activities'> 
+  <% for activity in activities %>
+    <% content_tag_for 'li', activity, :class=>'hentry' do %>
+      <%= format = today && activity.created_at.to_date < today ? '%b %d' : 
'%I:%M%p'
+          abbr_time activity.created_at, activity.created_at.strftime(format), 
:class=>'published' %>
+      <span class='entry-title'><%= activity_to_html activity, 
:person=>{:class=>'author'}, :task=>{:rel=>'bookmark'} %></span>
+    <% end %>
+  <% end %>
+</ol>

Modified: ode/sandbox/singleshot/app/views/activities/index.atom.builder
URL: 
http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/views/activities/index.atom.builder?rev=662645&r1=662644&r2=662645&view=diff
==============================================================================
--- ode/sandbox/singleshot/app/views/activities/index.atom.builder (original)
+++ ode/sandbox/singleshot/app/views/activities/index.atom.builder Mon Jun  2 
21:52:44 2008
@@ -1,14 +1,15 @@
 atom_feed :root_url=>activities_url do |feed|
   feed.title @title
   feed.subtitle @subtitle
-  feed.updated @activities.first.created_at
+  feed.updated @activities.first.created_at unless @activities.empty?
 
   for activity in @activities
-    feed.entry activity, :url=>task_url(activity.task) do |entry|
-      entry.title "#{activity.person.fullname} #{activity.action} 
#{activity.task.title}"
+    person, task = activity.person, activity.task
+    feed.entry activity, :url=>task_url(task) do |entry|
+      entry.title activity_to_text(activity)
       entry.content :type=>'html' do |content|
-        content.text! "<p>#{link_to h(activity.person.fullname), 
activity.person.identity} #{activity.action} #{link_to h(activity.task.title), 
task_url(activity.task)}</p>"
-        content.text!  truncate(strip_tags(activity.task.description), 250)
+        content.text! "<p>#{activity_to_html(activity)}</p>"
+        content.text!  truncate(strip_tags(task.description), 250)
       end
     end
   end

Modified: ode/sandbox/singleshot/app/views/activities/index.html.erb
URL: 
http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/views/activities/index.html.erb?rev=662645&r1=662644&r2=662645&view=diff
==============================================================================
--- ode/sandbox/singleshot/app/views/activities/index.html.erb (original)
+++ ode/sandbox/singleshot/app/views/activities/index.html.erb Mon Jun  2 
21:52:44 2008
@@ -1,17 +1,9 @@
+<% by_date = group_by_dates(@activities, :created_at) %>
 <ol class='dates hfeed'>
-  <% for day, activities in @days %>
-    <% content_tag_for 'li', day do %>
-      <h2><%= abbr_date day, relative_date(day).capitalize %></h2>
-      <ol class='activities'>
-        <% for activity in activities %>
-          <% content_tag_for 'li', activity, :class=>'hentry entry-title' do %>
-            <%= link_to h(activity.person.fullname), activity.person.url, 
:class=>'author fn url' %>
-            <%= activity.action %> the task
-            <%= link_to h(truncate(activity.task.title, 100)), 
task_url(activity.task),
-                  :rel=>'bookmark', 
:title=>truncate(strip_tags(activity.task.description), 250) %>
-          <% end %>
-        <% end %>
-      </ol>
-    <% end %>
+  <% for date, activities in by_date %>
+    <li class='date'>
+      <h2><%= date.humanize %></h2>
+      <%= render :partial=>'activities', :locals=>{ :activities=>activities } 
%>
+    </li>
   <% end %>
 </ol>

Modified: ode/sandbox/singleshot/app/views/activities/index.ics.ical
URL: 
http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/views/activities/index.ics.ical?rev=662645&r1=662644&r2=662645&view=diff
==============================================================================
--- ode/sandbox/singleshot/app/views/activities/index.ics.ical (original)
+++ ode/sandbox/singleshot/app/views/activities/index.ics.ical Mon Jun  2 
21:52:44 2008
@@ -4,7 +4,7 @@
 for activity in @activities
   calendar.event activity do |event|
     event.dtstart activity.created_at
-    event.summary "#{activity.person.fullname} #{activity.action} 
#{activity.task.title}"
+    event.summary activity_to_text(activity)
     event.description truncate(strip_tags(activity.task.description), 250)
     event.url task_url(activity.task)
   end

Modified: ode/sandbox/singleshot/app/views/tasks/completed.html.erb
URL: 
http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/views/tasks/completed.html.erb?rev=662645&r1=662644&r2=662645&view=diff
==============================================================================
--- ode/sandbox/singleshot/app/views/tasks/completed.html.erb (original)
+++ ode/sandbox/singleshot/app/views/tasks/completed.html.erb Mon Jun  2 
21:52:44 2008
@@ -1,14 +1,16 @@
-<ol class='dates'>
-  <% for day, tasks in @days %>
-    <% content_tag_for 'li', day do %>
-      <h2><%= abbr_date day, relative_date(day).capitalize %></h2>
-      <ol class='tasks'>
-        <% for task in tasks %>
-          <% content_tag_for 'li', task do %>
-            <%= link_to h(task.title), task_url(task), :rel=>'bookmark', 
:title=>truncate(strip_tags(task.description), 250) %>
+<% by_date = group_by_dates(@tasks, :updated_at) %>
+<ol class='dates hfeed'>
+  <% for date, tasks in by_date %>
+    <li class='date'>
+      <h2><%= date.humanize %></h2>
+        <ol class='tasks'> 
+          <% for task in tasks %>
+            <% content_tag_for 'li', task, :class=>'hentry' do %>
+              <%= abbr_time task.updated_at, 
task.updated_at.strftime('%I:%M%p'), :class=>'updated' %>
+              <%= link_to h(task.title), task_url(task), :rel=>'bookmark', 
:class=>'entry-title', :title=>truncate(strip_tags(task.description), 250) %>
+            <% end %>
           <% end %>
-        <% end %>
-      </ol>
-    <% end %>
+        </ol>
+    </li>
   <% end %>
 </ol>

Modified: ode/sandbox/singleshot/app/views/tasks/following.html.erb
URL: 
http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/views/tasks/following.html.erb?rev=662645&r1=662644&r2=662645&view=diff
==============================================================================
--- ode/sandbox/singleshot/app/views/tasks/following.html.erb (original)
+++ ode/sandbox/singleshot/app/views/tasks/following.html.erb Mon Jun  2 
21:52:44 2008
@@ -3,21 +3,21 @@
     <th style='width:6em'>Status</th>
     <th>Task</th>
     <th style='width:7em'>Due on</th>
-    <th style='width:4em'>Priority</th>
-    <th style='width:6em'>Age</th>
-    <th style='width:7em'>Assigned to</th>
+    <th style='width:5em'>Priority</th>
+    <th style='width:7em'>Age</th>
+    <th style='width:8em'>Assigned to</th>
   </thead>
   <tbody>
     <% for task in @tasks %>
       <% classes = ['hentry']
          classes << 'overdue' if task.over_due?
-         classes << 'inactive' if task.cancelled? || task.suspended?
+         classes << 'inactive' unless task.ready? || task.active?
          content_tag_for 'tr', task, :class=>classes.join(' ') do %>
         <td class='status'><%= task.status.titleize %></td>
-        <td class='entry-title'><%= '⚠  ' if task.over_due? %><%= link_to 
h(task.title), task_url(task), :rel=>'bookmark', 
:title=>truncate(strip_tags(task.description), 250) %></td>
-        <td><%= abbr_date task.due_on, relative_date(task.due_on).titleize, 
:class=>(task.over_due? ? 'overdue' : nil) if task.due_on %></td>
+        <td class='entry-title'><%= link_to h(task.title), task_url(task), 
:rel=>'bookmark', :title=>truncate(strip_tags(task.description), 250) %></td>
+        <td><%= image_tag('exclamation.png') if task.over_due? %> <%= 
abbr_date task.due_on, relative_date(task.due_on).titleize, 
:class=>(task.over_due? ? 'overdue' : nil) if task.due_on %></td>
         <td><%= content_tag 'span', ['High', 'Normal', 'Low'][task.priority - 
1], :class=>"priority_#{task.priority}" %></td>
-        <td><%= abbr_time task.created_at, relative_time(task.created_at), 
:class=>'published' %></td>
+        <td><%= abbr_time task.created_at, age(task.created_at, false), 
:class=>'published' %></td>
         <td><%= link_to_person task.owner, :owner if task.owner %></td>
       <% end %>
     <% end %>

Modified: ode/sandbox/singleshot/app/views/tasks/index.html.erb
URL: 
http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/views/tasks/index.html.erb?rev=662645&r1=662644&r2=662645&view=diff
==============================================================================
--- ode/sandbox/singleshot/app/views/tasks/index.html.erb (original)
+++ ode/sandbox/singleshot/app/views/tasks/index.html.erb Mon Jun  2 21:52:44 
2008
@@ -2,8 +2,8 @@
   <thead>
     <th>Task</th>
     <th style='width:7em'>Due on</th>
-    <th style='width:4em'>Priority</th>
-    <th style='width:6em'>Age</th>
+    <th style='width:5em'>Priority</th>
+    <th style='width:7em'>Age</th>
     <th style='width:5em'></th>
   </thead>
   <tbody>
@@ -12,7 +12,7 @@
         <td class='entry-title'><%= link_to h(task.title), task_url(task), 
:rel=>'bookmark', :title=>truncate(strip_tags(task.description), 250) %></td>
         <td><%= image_tag('exclamation.png') if task.over_due? %> <%= 
abbr_date task.due_on, relative_date(task.due_on).titleize if task.due_on 
%></td>
         <td><%= content_tag 'span', ['High', 'Normal', 'Low'][task.priority - 
1], :class=>"priority_#{task.priority}" %></td>
-        <td><%= abbr_time task.created_at, relative_time(task.created_at), 
:class=>'published' %></td>
+        <td><%= abbr_time task.created_at, age(task.created_at, false), 
:class=>'published' %></td>
         <td><%= button_to 'Claim', task_url(task, 
'task[owner]'=>authenticated), :method=>:put, :title=>'Claim this task' if 
task.can_claim?(authenticated) %></td>
       <% end %>
     <% end %>

Modified: ode/sandbox/singleshot/app/views/tasks/show.html.erb
URL: 
http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/views/tasks/show.html.erb?rev=662645&r1=662644&r2=662645&view=diff
==============================================================================
--- ode/sandbox/singleshot/app/views/tasks/show.html.erb (original)
+++ ode/sandbox/singleshot/app/views/tasks/show.html.erb Mon Jun  2 21:52:44 
2008
@@ -1,30 +1,24 @@
 <% div_for @task do %>
   <div class='bar'>
-    <div class='summary'>
-      <div class='vitals'><%= task_vitals(@task) %></div>
-      <div class='actions'><%= quick_actions(@task) %> <%= content_tag 
'button', '▽ More Options', :onclick=>"Singleshot.expand(event, '.expanded', 
'△ Less options')", :class=>'button-to' %></div>
+    <div class='bar-actions'>
+      <%= quick_actions(@task) %>
+      <%= content_tag 'button', 'More Options', 
:onclick=>"Singleshot.expand(event, '.expanded', 'Less options')", 
:class=>'button-to' %>
     </div>
-    <div class='expanded' style='display:none'>
+    <div class='vitals'>
+      <%= task_vitals(@task) %>: <%= content_tag 'span', h(@task.title), 
:class=>'title', :title=>@task.title %>
+    </div>
+    
+    <div class='expanded' style='display:one'>
+      <div><%= sanitize(simple_format(@task.description)) %></div>
       <%= link_to image_tag('calendar.png') + ' Calendar', 
formatted_task_url(@task, 'ics', :access_key=>authenticated.access_key),
           :rel=>'alternate', :title=>'Add this task to your calendar' %>
       <%= link_to image_tag('feed.png') + ' Activity', 
formatted_activity_url(@task, 'atom', :access_key=>authenticated.access_key),
           :rel=>'alternate', :title=>'Subscribe to see changes to this task' %>
-      <h2><%= h(@task.title) %></h2>
       <dl>
         <dt>Priority</dt><dd><%= ['High', 'Medium', 'Low'[EMAIL PROTECTED] - 
1] %></dd>
         <%= content_tag('dt', 'Due on') + content_tag('dd', 
relative_date(@task.due_on)) if @task.due_on %>
         <dt>Recent activity</dt>
-        <dd>
-          <ol class='activities hfeed'>
-            <% for activity in @task.activities %>
-              <% content_tag_for 'li', activity, :class=>'hentry entry-title' 
do %>
-                <%= link_to activity.person.fullname, activity.person.identity 
%>
-                <%= activity.action %>
-                <%= link_to activity.task.title, task_url(activity.task), 
:rel=>'bookmark' %>
-              <% end %>
-            <% end %>
-          </ol>
-        </dd>
+        <dd><%= render :file=>'activities/_activities', :locals=>{ 
:today=>Date.today, :activities=>@task.activities } %></dd>
         <%= admins = @task.admins.map { |person| link_to_person(person, 
:admin) }
             content_tag('dt', 'Admins') + content_tag('dd', 
admins.to_sentence) unless admins.empty? %>
         <%= observers = @task.observers.map { |person| link_to_person(person, 
:observer) }
@@ -35,10 +29,11 @@
       </div>
     </div>
   </div>
-  <div class='description'><%= sanitize(simple_format(@task.description)) 
%></div>
+
   <%= task_frame @task %>
+
   <% unless @task.form_completing %>
     <div class='completion'><div class='actions'><%= button_to 'Completed', 
task_url(@task, :status=>'completed'), :title=>'Click when task completed' 
%></div></div>
   <% end %>
-  <%= javascript_tag 'Singleshot.taskView()' %>
+  <%= javascript_tag "Singleshot.taskView('task_frame')" %>
 <% end %>

Modified: ode/sandbox/singleshot/db/migrate/20080506015153_create_activities.rb
URL: 
http://svn.apache.org/viewvc/ode/sandbox/singleshot/db/migrate/20080506015153_create_activities.rb?rev=662645&r1=662644&r2=662645&view=diff
==============================================================================
--- ode/sandbox/singleshot/db/migrate/20080506015153_create_activities.rb 
(original)
+++ ode/sandbox/singleshot/db/migrate/20080506015153_create_activities.rb Mon 
Jun  2 21:52:44 2008
@@ -2,7 +2,7 @@
   def self.up
     create_table  'activities' do |t|
       t.belongs_to  'person'
-      t.belongs_to  'task'
+      t.belongs_to  'task',       :null=>false
       t.string      'action',     :null=>false
       t.datetime    'created_at', :null=>false
     end

Modified: ode/sandbox/singleshot/db/schema.rb
URL: 
http://svn.apache.org/viewvc/ode/sandbox/singleshot/db/schema.rb?rev=662645&r1=662644&r2=662645&view=diff
==============================================================================
--- ode/sandbox/singleshot/db/schema.rb (original)
+++ ode/sandbox/singleshot/db/schema.rb Mon Jun  2 21:52:44 2008
@@ -13,7 +13,7 @@
 
   create_table "activities", :force => true do |t|
     t.integer  "person_id"
-    t.integer  "task_id"
+    t.integer  "task_id",    :null => false
     t.string   "action",     :null => false
     t.datetime "created_at", :null => false
   end

Modified: ode/sandbox/singleshot/public/javascripts/application.js
URL: 
http://svn.apache.org/viewvc/ode/sandbox/singleshot/public/javascripts/application.js?rev=662645&r1=662644&r2=662645&view=diff
==============================================================================
--- ode/sandbox/singleshot/public/javascripts/application.js (original)
+++ ode/sandbox/singleshot/public/javascripts/application.js Mon Jun  2 
21:52:44 2008
@@ -3,10 +3,16 @@
 //
 var Singleshot = {
   // Returns the SingleShot.TaskView object.
-  taskView: function() {
-    var taskView = new Singleshot.TaskView();
-    Singleshot.taskView = function() { return taskView };
-    return taskView;
+  taskView: function(target) {
+    target = $$(target).first() || $(target);
+    // Adjust lower frame to expand and fit the reminder of the window.
+    // Do it once now, and each time the window is resized.
+    var adjust = function() {
+      target.style.height = window.innerHeight - target.offsetTop;
+    }
+    Event.observe(window, 'resize', adjust);
+    adjust();
+    Singleshot.taskView = function() { };
   },
 
   expand: function(event, target, alternative) {
@@ -27,21 +33,3 @@
     Event.stop(event);
   }
 }
-
-Singleshot.TaskView = Class.create({
-  initialize: function() {
-    this.adjustFrame('task_frame');
-  },
-
-  adjustFrame: function(ifr) {
-    // Adjust lower frame to expand and fit the reminder of the window.
-    // Do it once now, and each time the window is resized.
-    if (ifr = $(ifr)) {
-      var adjust = function() {
-        ifr.style.height = window.innerHeight - ifr.offsetTop;
-      }
-      Event.observe(window, 'resize', adjust);
-      adjust();
-    }
-  }
-});

Modified: ode/sandbox/singleshot/public/stylesheets/default.css
URL: 
http://svn.apache.org/viewvc/ode/sandbox/singleshot/public/stylesheets/default.css?rev=662645&r1=662644&r2=662645&view=diff
==============================================================================
--- ode/sandbox/singleshot/public/stylesheets/default.css (original)
+++ ode/sandbox/singleshot/public/stylesheets/default.css Mon Jun  2 21:52:44 
2008
@@ -194,6 +194,7 @@
   margin: 0;
   padding:2em 2.5em 2em 2.5em;
   font-size: 1.1em;
+  table-layout: fixed;
 }
 table.tasks thead th {
   text-align: left;
@@ -208,12 +209,15 @@
   padding: 0.5em;
   margin: 0;
   border-bottom: 1px solid #ddd;
+  text-overflow: ellipsis;
+       overflow: hidden;
+       white-space: nowrap;
 }
 table.tasks tbody td img {
   vertical-align: middle;
 }
 table.tasks tbody tr.inactive, table.tasks tbody tr.inactive td a {
-  color: #ccc;
+  color: #888;
 }
 table.tasks tbody tr.overdue td, table.tasks tbody .overdue td a {
   color: red;
@@ -222,6 +226,9 @@
   color: red;
 }
 
+
+/** Chronological list **/
+
 ol.dates {
   font-size: 1.1em;
   list-style: none;
@@ -243,6 +250,11 @@
 ol.dates li.date ol.tasks li.task {
   margin: 0 0 1.0em 0;
 }
+ol.dates li.date abbr.updated {
+  color: #666;
+  font-size: 0.8em;
+  margin-right: 0.6em;
+}
 
 
 /** Activities **/
@@ -254,52 +266,75 @@
 ol.activities li.activity {
   margin: 0 0 1.0em 0;
 }
+ol.activities li.activity abbr.published {
+  color: #666;
+  font-size: 0.8em;
+  margin-right: 0.6em;
+}
 
 
 /** Single task **/
 
-div.task {
+
+table.summary {
+  width: 100%;
+  border-spacing: 0;
+  border-padding: 0;
+  border: none;
+  margin: 0;
+  padding:0 2.5em 0 2.5em;
+  table-layout: fixed;
+  font-size: 1.1em;
+}
+table.summary td {
   margin: 0;
   padding: 0;
+  white-space: nowrap; 
+}
+table.summary td.title {
+  text-overflow: ellipsis;
+  overflow: hidden;
+  white-space: nowrap; 
 }
+table.summary td.actions {
+  text-align: right;
+}
+
 
+
+
+
+div.task {
+  margin: 0;
+  padding: 0;
+}
 div.task div.bar {
-  position:absolute;
+  position: absolute;
   width: 100%;
-  margin:0;
-  padding:0;
+  margin: 0;
+  padding: 0;
   border-bottom: solid 2px #046380;
   background-color: #e0e0e0;
 }
 
-div.task div.bar div.summary {
-  height:2em;
-  padding-top:0.3em;
-  padding: 0.5em 3em 3px 3em;
-}
-div.task div.bar div.summary h1 {
-  margin: 0;
-  font-size: 1.5em;
-  display: inline;
-}
-div.task div.bar div.summary h1 a {
-  color: #000;
-  text-decoration: none;
-}
-div.task div.bar div.summary a {
-  text-decoration: none;
+div.task div.bar div.vitals {
+  margin: 0.6em 0em 0 3em;
+  font-size: 1.1em;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  white-space: nowrap;
 }
-div.task div.bar div.summary div.vitals {
-  padding-top: 0.3em;
+div.task div.bar div.vitals span.title {
+  font-weight: bold;
 }
-div.task div.bar div.summary div.actions {
+div.task div.bar div.bar-actions {
   display: inline;
-  position: absolute;
-  right: 3em;
-  top: 0.5em;
+  background: #e0e0e0;
+  float: right;
+  margin: 0.5em 2.5em 0.5em 0;
 }
-div.task div.bar div.summary .button-to {
-  margin-left: 1em;
+div.task div.bar div.bar-actions .button-to {
+  margin-left: 0.6em;
 }
 
 div.task div.bar div.expanded {
@@ -349,7 +384,7 @@
   width: 100%;
   height: 0;
   padding: 0;
-  margin: 0;
+  margin: 3em 0 0 0;
   background: transparent;
 }
 


Reply via email to