Introduced user preference for time zone (migration, model and prefs forms)

Made all dates and times stored in UTC in the database and presented according to the User's preferred time zone.
Cleaned up old unused preference methods in UserController
Restored keyboard shortcuts for date field interaction
Aliased preference in User model to prefs for brevity

Don't forget to rake db:migrate for this update!

All tests pass, but there were a lot of little changes involved in this feature. Please help me test it thoroughly if you're using the trunk. 
 
Fixes #349



git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@392 a4c988fc-2ded-0310-b66e-134b36920a42
This commit is contained in:
lukemelia 2007-01-06 10:06:33 +00:00
parent 9a444be3fe
commit 2329cb8e1e
30 changed files with 218 additions and 191 deletions

View file

@ -62,18 +62,17 @@ class ApplicationController < ActionController::Base
wants.xml { render :text => 'An error occurred on the server.' + $! }
end
end
private
def get_current_user
@user = User.find(session['user_id']) if session['user_id']
@prefs = @user.preference unless @user.nil?
@prefs = @user.prefs unless @user.nil?
end
def parse_date_per_user_prefs( s )
return nil if s.blank?
Date.strptime(s, @user.preference.date_format)
#Chronic.parse(s).to_date
@user.prefs.tz.unadjust(Date.strptime(s, @user.prefs.date_format)).utc.to_date
end
def init_data_for_sidebar

View file

@ -90,8 +90,8 @@ protected
if params.key?('due')
due_within = params['due'].to_i
condition_builder.add('todos.due <= ?', due_within.days.from_now)
due_within_date_s = due_within.days.from_now.strftime("%Y-%m-%d")
condition_builder.add('todos.due <= ?', due_within.days.from_now.utc)
due_within_date_s = @user.prefs.tz.adjust(due_within.days.from_now.utc).strftime("%Y-%m-%d")
@title << " due today" if (due_within == 0)
@title << " due within a week" if (due_within == 6)
@description << " with a due date #{due_within_date_s} or earlier"
@ -99,7 +99,7 @@ protected
if params.key?('done')
done_in_last = params['done'].to_i
condition_builder.add('todos.completed_at >= ?', done_in_last.days.ago)
condition_builder.add('todos.completed_at >= ?', done_in_last.days.ago.utc)
@title << " actions completed"
@description << " in the last #{done_in_last.to_s} days"
end

View file

@ -16,7 +16,7 @@ class TodoController < ApplicationController
# If you've set no_completed to zero, the completed items box
# isn't shown on the home page
max_completed = @user.preference.show_number_completed
max_completed = @user.prefs.show_number_completed
@done = @user.completed_todos.find(:all, :limit => max_completed) unless max_completed == 0
@contexts_to_show = @contexts.reject {|x| x.hide? }
@ -60,7 +60,7 @@ class TodoController < ApplicationController
if @item.due?
@date = parse_date_per_user_prefs(p['todo']['due'])
@item.due = @date.to_s(:db)
@item.due = @date
else
@item.due = ""
end
@ -206,15 +206,15 @@ class TodoController < ApplicationController
def completed
@page_title = "TRACKS::Completed tasks"
@done = @user.completed_todos
@done_today = @done.completed_within 1.day.ago
@done_this_week = @done.completed_within 1.week.ago
@done_this_month = @done.completed_within 4.week.ago
@done_today = @done.completed_within 1.day.ago.utc
@done_this_week = @done.completed_within 1.week.ago.utc
@done_this_month = @done.completed_within 4.week.ago.utc
end
def completed_archive
@page_title = "TRACKS::Archived completed tasks"
@done = @user.completed_todos
@done_archive = @done.completed_more_than 28.day.ago
@done_archive = @done.completed_more_than 28.day.ago.utc
end
def tickler

View file

@ -39,28 +39,6 @@ class UserController < ApplicationController
end
end
def preferences
@page_title = "TRACKS::Preferences"
@prefs = @user.preference
end
def edit_preferences
@page_title = "TRACKS::Edit Preferences"
@prefs = @user.preference
render :action => "preference_edit_form", :object => @prefs
end
def update_preferences
user_success = @user.update_attributes(params['user'])
prefs_success = @user.preference.update_attributes(params['prefs'])
if user_success && prefs_success
redirect_to :action => 'preferences'
else
render :action => 'edit_preferences'
end
end
def change_password
@page_title = "TRACKS::Change password"
end

View file

@ -6,12 +6,17 @@ module ApplicationHelper
#
def format_date(date)
if date
date_format = @user.preference.date_format
formatted_date = date.strftime("#{date_format}")
date_format = @user.prefs.date_format
formatted_date = @user.prefs.tz.adjust(date).strftime("#{date_format}")
else
formatted_date = ''
end
end
def user_time
@user.prefs.tz.adjust(Time.now.utc)
end
# Uses RedCloth to transform text using either Textile or Markdown
# Need to require redcloth above
@ -39,6 +44,11 @@ module ApplicationHelper
"<a href=\"#{url}\"#{tag_options}#{id_tag}>#{name || url}</a>"
end
def days_from_today(date)
today = Time.now.utc.to_date
@user.prefs.tz.adjust(date).to_date - @user.prefs.tz.adjust(today).to_date
end
# Check due date in comparison to today's date
# Flag up date appropriately with a 'traffic light' colour code
#
@ -47,27 +57,26 @@ module ApplicationHelper
return ""
end
@now = Date.today
@days = due-@now
days = days_from_today(due)
case @days
case days
# overdue or due very soon! sound the alarm!
when -1000..-1
"<a title='" + format_date(due) + "'><span class=\"red\">Overdue by " + (@days * -1).to_s + " days</span></a> "
"<a title='" + format_date(due) + "'><span class=\"red\">Overdue by " + (days * -1).to_s + " days</span></a> "
when 0
"<a title='" + format_date(due) + "'><span class=\"amber\">Due Today</span></a> "
when 1
"<a title='" + format_date(due) + "'><span class=\"amber\">Due Tomorrow</span></a> "
# due 2-7 days away
when 2..7
if @user.preference.due_style == "1"
if @user.prefs.due_style == "1"
"<a title='" + format_date(due) + "'><span class=\"orange\">Due on " + due.strftime("%A") + "</span></a> "
else
"<a title='" + format_date(due) + "'><span class=\"orange\">Due in " + @days.to_s + " days</span></a> "
"<a title='" + format_date(due) + "'><span class=\"orange\">Due in " + days.to_s + " days</span></a> "
end
# more than a week away - relax
else
"<a title='" + format_date(due) + "'><span class=\"green\">Due in " + @days.to_s + " days</span></a> "
"<a title='" + format_date(due) + "'><span class=\"green\">Due in " + days.to_s + " days</span></a> "
end
end
@ -80,10 +89,9 @@ module ApplicationHelper
return ""
end
@now = Date.today
@days = due-@now
days = days_from_today(due)
case @days
case days
# overdue or due very soon! sound the alarm!
when -1000..-1
"<span class=\"red\">" + format_date(due) +"</span>"
@ -130,13 +138,13 @@ module ApplicationHelper
def item_link_to_context(item)
descriptor = "[C]"
descriptor = "[#{item.context.name}]" if (@user.preference.verbose_action_descriptors)
descriptor = "[#{item.context.name}]" if (@user.prefs.verbose_action_descriptors)
link_to_context( item.context, descriptor )
end
def item_link_to_project(item)
descriptor = "[P]"
descriptor = "[#{item.project.name}]" if (@user.preference.verbose_action_descriptors)
descriptor = "[#{item.project.name}]" if (@user.prefs.verbose_action_descriptors)
link_to_project( item.project, descriptor )
end

View file

@ -42,11 +42,11 @@ module TodoHelper
def staleness_class(item)
if item.due || item.completed?
return ""
elsif item.created_at < (@user.preference.staleness_starts * 3).days.ago
elsif item.created_at < (@user.prefs.staleness_starts * 3).days.ago.utc
return " stale_l3"
elsif item.created_at < (@user.preference.staleness_starts * 2).days.ago
elsif item.created_at < (@user.prefs.staleness_starts * 2).days.ago.utc
return " stale_l2"
elsif item.created_at < (@user.preference.staleness_starts).days.ago
elsif item.created_at < (@user.prefs.staleness_starts).days.ago.utc
return " stale_l1"
else
return ""
@ -61,33 +61,32 @@ module TodoHelper
return ""
end
@now = Date.today
@days = due-@now
days = days_from_today(due)
case @days
case days
# overdue or due very soon! sound the alarm!
when -1000..-1
"<a title='" + format_date(due) + "'><span class=\"red\">Shown on " + (@days * -1).to_s + " days</span></a> "
"<a title='" + format_date(due) + "'><span class=\"red\">Shown on " + (days * -1).to_s + " days</span></a> "
when 0
"<a title='" + format_date(due) + "'><span class=\"amber\">Show Today</span></a> "
when 1
"<a title='" + format_date(due) + "'><span class=\"amber\">Show Tomorrow</span></a> "
# due 2-7 days away
when 2..7
if @user.preference.due_style == 1
if @user.prefs.due_style == 1
"<a title='" + format_date(due) + "'><span class=\"orange\">Show on " + due.strftime("%A") + "</span></a> "
else
"<a title='" + format_date(due) + "'><span class=\"orange\">Show in " + @days.to_s + " days</span></a> "
"<a title='" + format_date(due) + "'><span class=\"orange\">Show in " + days.to_s + " days</span></a> "
end
# more than a week away - relax
else
"<a title='" + format_date(due) + "'><span class=\"green\">Show in " + @days.to_s + " days</span></a> "
"<a title='" + format_date(due) + "'><span class=\"green\">Show in " + days.to_s + " days</span></a> "
end
end
def calendar_setup( input_field )
date_format = @user.preference.date_format
week_starts = @user.preference.week_starts
date_format = @user.prefs.date_format
week_starts = @user.prefs.week_starts
str = "Calendar.setup({ ifFormat:\"#{date_format}\""
str << ",firstDay:#{week_starts},showOthers:true,range:[2004, 2010]"
str << ",step:1,inputField:\"" + input_field + "\",cache:true,align:\"TR\" })\n"

View file

@ -1,6 +1,9 @@
class Preference < ActiveRecord::Base
belongs_to :user
composed_of :tz,
:class_name => 'TimeZone',
:mapping => %w(time_zone name)
def self.day_number_to_name_map
{ 0 => "Sunday",
1 => "Monday",

View file

@ -9,7 +9,7 @@ class Todo < ActiveRecord::Base
state :active, :enter => Proc.new { |t| t[:show_from] = nil }
state :project_hidden
state :completed, :enter => Proc.new { |t| t.completed_at = Time.now() }, :exit => Proc.new { |t| t.completed_at = nil }
state :completed, :enter => Proc.new { |t| t.completed_at = Time.now.utc }, :exit => Proc.new { |t| t.completed_at = nil }
state :deferred
event :defer do
@ -45,7 +45,7 @@ class Todo < ActiveRecord::Base
validates_presence_of :context
def validate
if deferred? && !show_from.blank? && show_from < Date.today()
if deferred? && !show_from.blank? && show_from < Time.now.utc.to_date
errors.add("Show From", "must be a date in the future.")
end
end
@ -65,7 +65,7 @@ class Todo < ActiveRecord::Base
def show_from=(date)
activate! if deferred? && date.blank?
defer! if active? && !date.blank? && date > Date.today()
defer! if active? && !date.blank? && date > Time.now.utc.to_date
self[:show_from] = date
end
@ -78,7 +78,7 @@ class Todo < ActiveRecord::Base
alias_method :original_set_initial_state, :set_initial_state
def set_initial_state
if show_from && (show_from > Date.today)
if show_from && (show_from > Time.now.utc.to_date)
write_attribute self.class.state_column, 'deferred'
else
original_set_initial_state

View file

@ -15,7 +15,7 @@ class User < ActiveRecord::Base
:conditions => [ 'state = ?', 'deferred' ],
:order => 'show_from ASC, created_at DESC' do
def find_and_activate_ready
find(:all, :conditions => ['show_from <= ?', Date.today ]).collect { |t| t.activate_and_save! }
find(:all, :conditions => ['show_from <= ?', Time.now.utc.to_date ]).collect { |t| t.activate_and_save! }
end
end
has_many :completed_todos,
@ -45,6 +45,8 @@ class User < ActiveRecord::Base
validates_inclusion_of :auth_type, :in => Tracks::Config.auth_schemes, :message=>"not a valid authentication type"
validates_presence_of :open_id_url, :if => Proc.new{|user| user.auth_type == 'open_id'}
alias_method :prefs, :preference
def self.authenticate(login, pass)
candidate = find(:first, :conditions => ["login = ?", login])
return nil if candidate.nil?

View file

@ -1,6 +1,6 @@
<div id="display_box">
<%= render :partial => "context/context", :locals => { :context => @context, :collapsible => false } %>
<%= render :partial => "todo/completed", :locals => { :done => @done, :collapsible => false, :append_descriptor => "in this context (last #{@user.preference.show_number_completed})" } %>
<%= render :partial => "todo/completed", :locals => { :done => @done, :collapsible => false, :append_descriptor => "in this context (last #{@user.prefs.show_number_completed})" } %>
</div><!-- [end:display_box] -->

View file

@ -27,7 +27,7 @@
<% if @count %>
<span id="badge_count" class="badge"><%= @count %></span>
<% end %>
<%= Time.now.strftime("%A, %d %B %Y") %> <%= image_tag("spinner.gif", :size => "16X16", :border => 0, :id => 'busy', :style => 'display:none' ) %>
<%= user_time.strftime("%A, %d %B %Y") %> <%= image_tag("spinner.gif", :size => "16X16", :border => 0, :id => 'busy', :style => 'display:none' ) %>
</h1>
</div>
<div id="minilinks">

View file

@ -1,7 +1,7 @@
<span class="errors">
<%= error_messages_for("item") %>
</span>
<% this_year = Date.today.strftime("%Y").to_i -%>
<% this_year = user_time.to_date.strftime("%Y").to_i -%>
<p><label for="item_state">Done?</label></p>
<p><%= check_box( "item", "state", "tabindex" => 1) %></p>
<p><label for="item_description">Next action</label></p>

View file

@ -3,6 +3,8 @@
<p>The preference settings should mostly be self-explanatory, but some hints are included below: </p>
<ul>
<li><strong>first name and last name:</strong> Used for display purposes if set</li>
<li><strong>time zone:</strong> your local time zone</li>
<li><strong>date format:</strong> the format in which you'd like dates to be shown. For example, for the date 31st January 2006, %d/%m/%Y will show 31/01/2006, %b-%e-%y will show Jan-31-06. See the <a href="http://uk2.php.net/strftime" title="PHP strftime manual">strftime manual</a> for more formatting options for the date.</li>
<li><strong>week starts:</strong> day of the week shown as the start of the week on the popup calendar.</li>
<li><strong>due style:</strong> style in which due dates are shown, e.g. "Due in 3 days", "Due on Wednesday"</li>
<li><strong>show completed projects in sidebar:</strong> whether or not projects marked as complete are shown in the sidebar on the home page and elsewhere</li>
@ -11,7 +13,6 @@
<li><strong>admin email:</strong> email address for the admin user of Tracks (displayed on the signup page for users to contact to obtain an account)</li>
<% end %>
<li><strong>staleness starts:</strong> the number of days before items with no due date get marked as stale (with a yellow highlight)</li>
<li><strong>date format:</strong> the format in which you'd like dates to be shown. For example, for the date 31st January 2006, %d/%m/%Y will show 31/01/2006, %b-%e-%y will show Jan-31-06. See the <a href="http://uk2.php.net/strftime" title="PHP strftime manual">strftime manual</a> for more formatting options for the date.</li>
<li><strong>show number completed:</strong> number of completed actions to show on the home page. If you set this to zero, the completed actions box will not be shown on the home page or on the individual context or project pages. You can still see all your completed items by clicking the 'Done' link in the navigation bar at the top of each page.</li>
<li><strong>refresh:</strong> automatic refresh interval for each of the pages (in minutes)</li>
<li><strong>verbose action descriptor:</strong> when true, show project/context name in action listing; when false show [P]/[C] with tool tips</li>
@ -46,7 +47,9 @@
table_row(pref_name, nowrap_label) { text_field('prefs', pref_name) }
end
%>
<%= table_row('time_zone', false) { time_zone_select('prefs','time_zone') } %>
<%= row_with_text_field('date_format') %>
<%= row_with_select_field("week_starts", Preference.day_number_to_name_map.invert.sort{|a,b| a[1]<=>b[1]})%>
<%= row_with_select_field("due_style", [['Due in ___ days',0],['Due on _______',1]]) %>
<%= row_with_select_field("show_completed_projects_in_sidebar") %>
@ -56,7 +59,6 @@
<% if @user.is_admin? %> <%= row_with_text_field('admin_email') %> <% end %>
<%= row_with_text_field('staleness_starts', true) %>
<%= row_with_text_field('date_format') %>
<%= row_with_text_field('show_number_completed') %>
<%= row_with_text_field('refresh') %>
<%= row_with_select_field("verbose_action_descriptors") %>

View file

@ -5,6 +5,7 @@
<ul id="prefs">
<li>First name: <span class="highlight"><%= @user.first_name %></span></li>
<li>Last name: <span class="highlight"><%= @user.last_name %></span></li>
<li>Time zone: <span class="highlight"><%= @prefs.tz %></span></li>
<li>Date format: <span class="highlight"><%= @prefs.date_format %></span></li>
<li>Week starts on: <span class="highlight"><%= Preference.day_number_to_name_map[@prefs.week_starts] %></span></li>
<li>Show the last <span class="highlight"><%= @prefs.show_number_completed %></span> completed items on the home page</li>

View file

@ -4,13 +4,13 @@
:locals => { :list_name => 'Active Projects',
:projects => @projects.select{|p| p.active? } } -%>
<% if @user.preference.show_hidden_projects_in_sidebar -%>
<% if @user.prefs.show_hidden_projects_in_sidebar -%>
<%= render :partial => "sidebar/project_list",
:locals => { :list_name => 'Hidden Projects',
:projects => @projects.select{|p| p.hidden? } } -%>
<% end -%>
<% if @user.preference.show_completed_projects_in_sidebar -%>
<% if @user.prefs.show_completed_projects_in_sidebar -%>
<%= render :partial => "sidebar/project_list",
:locals => { :list_name => 'Completed Projects',
:projects => @projects.select{|p| p.completed? } } -%>
@ -20,7 +20,7 @@
:locals => { :list_name => 'Active Contexts',
:contexts => @contexts.reject{|c| c.hide? } } -%>
<% if @user.preference.show_hidden_contexts_in_sidebar -%>
<% if @user.prefs.show_hidden_contexts_in_sidebar -%>
<%= render :partial => "sidebar/context_list",
:locals => { :list_name => 'Hidden Contexts',
:contexts => @contexts.select{|c| c.hide? } } -%>

View file

@ -2,7 +2,7 @@ if @saved
page[@item].remove
if @item.completed?
# Don't try to insert contents into a non-existent container!
unless @user.preference.hide_completed_actions?
unless @user.prefs.hide_completed_actions?
page.insert_html :top, "completed", :partial => 'todo/item', :locals => { :parent_container_type => "completed" }
page.visual_effect :highlight, dom_id(@item, 'line'), {'startcolor' => "'#99ff99'"}
page[empty_container_msg_div_id].show if @down_count == 0 && !empty_container_msg_div_id.nil?

View file

@ -1,7 +1,5 @@
class PrefToShowHiddenProjectsInSidebar < ActiveRecord::Migration
class Preferences < ActiveRecord::Base; end
def self.up
add_column :preferences, :show_hidden_projects_in_sidebar, :boolean, :default => true, :null => false
end

View file

@ -0,0 +1,11 @@
class AddTimeZonePreference < ActiveRecord::Migration
def self.up
add_column :preferences, :time_zone, :string, :limit => 255, :default => 'London', :null => false
end
def self.down
remove_column :preferences, :time_zone
end
end

View file

@ -1,96 +1,97 @@
# This file is autogenerated. Instead of editing this file, please use the
# migrations feature of ActiveRecord to incrementally modify your database, and
# then regenerate this schema definition.
ActiveRecord::Schema.define(:version => 20) do
create_table "contexts", :force => true do |t|
t.column "name", :string, :default => "", :null => false
t.column "position", :integer, :default => 0, :null => false
t.column "hide", :boolean, :default => false
t.column "user_id", :integer, :default => 1
end
create_table "notes", :force => true do |t|
t.column "user_id", :integer, :default => 0, :null => false
t.column "project_id", :integer, :default => 0, :null => false
t.column "body", :text
t.column "created_at", :datetime
t.column "updated_at", :datetime
end
create_table "open_id_associations", :force => true do |t|
t.column "server_url", :binary
t.column "handle", :string
t.column "secret", :binary
t.column "issued", :integer
t.column "lifetime", :integer
t.column "assoc_type", :string
end
create_table "open_id_nonces", :force => true do |t|
t.column "nonce", :string
t.column "created", :integer
end
create_table "open_id_settings", :force => true do |t|
t.column "setting", :string
t.column "value", :binary
end
create_table "preferences", :force => true do |t|
t.column "user_id", :integer, :default => 0, :null => false
t.column "date_format", :string, :limit => 40, :default => "%d/%m/%Y", :null => false
t.column "week_starts", :integer, :default => 0, :null => false
t.column "show_number_completed", :integer, :default => 5, :null => false
t.column "staleness_starts", :integer, :default => 7, :null => false
t.column "show_completed_projects_in_sidebar", :boolean, :default => true, :null => false
t.column "show_hidden_contexts_in_sidebar", :boolean, :default => true, :null => false
t.column "due_style", :integer, :default => 0, :null => false
t.column "admin_email", :string, :default => "butshesagirl@rousette.org.uk", :null => false
t.column "refresh", :integer, :default => 0, :null => false
t.column "verbose_action_descriptors", :boolean, :default => false, :null => false
t.column "show_hidden_projects_in_sidebar", :boolean, :default => true, :null => false
end
create_table "projects", :force => true do |t|
t.column "name", :string, :default => "", :null => false
t.column "position", :integer, :default => 0, :null => false
t.column "user_id", :integer, :default => 1
t.column "description", :text
t.column "state", :string, :limit => 20, :default => "active", :null => false
end
create_table "sessions", :force => true do |t|
t.column "session_id", :string
t.column "data", :text
t.column "updated_at", :datetime
end
add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
create_table "todos", :force => true do |t|
t.column "context_id", :integer, :default => 0, :null => false
t.column "project_id", :integer
t.column "description", :string, :default => "", :null => false
t.column "notes", :text
t.column "created_at", :datetime
t.column "due", :date
t.column "completed_at", :datetime
t.column "user_id", :integer, :default => 1
t.column "show_from", :date
t.column "state", :string, :limit => 20, :default => "immediate", :null => false
end
create_table "users", :force => true do |t|
t.column "login", :string, :limit => 80, :default => "", :null => false
t.column "password", :string, :limit => 40, :default => "", :null => false
t.column "word", :string
t.column "is_admin", :boolean, :default => false, :null => false
t.column "first_name", :string
t.column "last_name", :string
t.column "auth_type", :string, :default => "database", :null => false
t.column "open_id_url", :string
end
end
# This file is autogenerated. Instead of editing this file, please use the
# migrations feature of ActiveRecord to incrementally modify your database, and
# then regenerate this schema definition.
ActiveRecord::Schema.define(:version => 21) do
create_table "contexts", :force => true do |t|
t.column "name", :string, :default => "", :null => false
t.column "hide", :integer, :limit => 4, :default => 0, :null => false
t.column "position", :integer, :default => 0, :null => false
t.column "user_id", :integer, :default => 0, :null => false
end
create_table "notes", :force => true do |t|
t.column "user_id", :integer, :default => 0, :null => false
t.column "project_id", :integer, :default => 0, :null => false
t.column "body", :text
t.column "created_at", :datetime
t.column "updated_at", :datetime
end
create_table "open_id_associations", :force => true do |t|
t.column "server_url", :binary
t.column "handle", :string
t.column "secret", :binary
t.column "issued", :integer
t.column "lifetime", :integer
t.column "assoc_type", :string
end
create_table "open_id_nonces", :force => true do |t|
t.column "nonce", :string
t.column "created", :integer
end
create_table "open_id_settings", :force => true do |t|
t.column "setting", :string
t.column "value", :binary
end
create_table "preferences", :force => true do |t|
t.column "user_id", :integer, :default => 0, :null => false
t.column "date_format", :string, :limit => 40, :default => "%d/%m/%Y", :null => false
t.column "week_starts", :integer, :default => 0, :null => false
t.column "show_number_completed", :integer, :default => 5, :null => false
t.column "staleness_starts", :integer, :default => 7, :null => false
t.column "show_completed_projects_in_sidebar", :boolean, :default => true, :null => false
t.column "show_hidden_contexts_in_sidebar", :boolean, :default => true, :null => false
t.column "due_style", :integer, :default => 0, :null => false
t.column "admin_email", :string, :default => "butshesagirl@rousette.org.uk", :null => false
t.column "refresh", :integer, :default => 0, :null => false
t.column "verbose_action_descriptors", :boolean, :default => false, :null => false
t.column "show_hidden_projects_in_sidebar", :boolean, :default => true, :null => false
t.column "time_zone", :string, :default => "London", :null => false
end
create_table "projects", :force => true do |t|
t.column "name", :string, :default => "", :null => false
t.column "position", :integer, :default => 0, :null => false
t.column "user_id", :integer, :default => 0, :null => false
t.column "description", :text
t.column "state", :string, :limit => 20, :default => "active", :null => false
end
create_table "sessions", :force => true do |t|
t.column "session_id", :string
t.column "data", :text
t.column "updated_at", :datetime
end
add_index "sessions", ["session_id"], :name => "sessions_session_id_index"
create_table "todos", :force => true do |t|
t.column "context_id", :integer, :default => 0, :null => false
t.column "description", :string, :limit => 100, :default => "", :null => false
t.column "notes", :text
t.column "created_at", :datetime
t.column "due", :date
t.column "completed_at", :datetime
t.column "project_id", :integer
t.column "user_id", :integer, :default => 0, :null => false
t.column "show_from", :date
t.column "state", :string, :limit => 20, :default => "immediate", :null => false
end
create_table "users", :force => true do |t|
t.column "login", :string, :limit => 80
t.column "password", :string, :limit => 40
t.column "word", :string
t.column "is_admin", :integer, :limit => 4, :default => 0, :null => false
t.column "first_name", :string
t.column "last_name", :string
t.column "auth_type", :string, :default => "database", :null => false
t.column "open_id_url", :string
end
end

View file

@ -33,7 +33,7 @@ module Tracks
def find_done_todos
self.todos.find(:all, :conditions => ["todos.state = ?", "completed"],
:order => "todos.completed_at DESC", :limit => self.user.preference.show_number_completed)
:order => "todos.completed_at DESC", :limit => self.user.prefs.show_number_completed)
end
def not_done_todo_count(opts={})

View file

@ -213,9 +213,8 @@ Calendar.setup = function (params) {
* they still work properly. Pressing '+' when no date is entered in the
* field will set the date to tomorrow, and likewise '-' with no date
* entered will set the date to yesterday.
* 2006-10-24: Commented out while trying to use Chronic library for the field
*/
/*DateDueKeyboardShortcutSupport = Class.create();
DateDueKeyboardShortcutSupport = Class.create();
DateDueKeyboardShortcutSupport.prototype = {
initialize: function(element, dateFormat) {
this.element = $(element);
@ -298,4 +297,4 @@ DateDueKeyboardShortcutSupport.prototype = {
((event.which) ? event.which : 0));
return String.fromCharCode(charCode);
}
};*/
};

View file

@ -1,15 +1,15 @@
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
<%
def today
Time.now.to_s(:db)
Time.now.utc.to_s(:db)
end
def next_week
1.week.from_now.to_s(:db)
1.week.from_now.utc.to_s(:db)
end
def last_week
1.week.ago.to_s(:db)
1.week.ago.utc.to_s(:db)
end
%>

View file

@ -12,6 +12,7 @@ admin_user_prefs:
week_starts: 1
due_style: 0
refresh: 0
time_zone: "London"
verbose_action_descriptors: true
other_user_prefs:
@ -27,4 +28,5 @@ other_user_prefs:
week_starts: 1
due_style: 0
refresh: 0
time_zone: "London"
verbose_action_descriptors: false

View file

@ -2,19 +2,19 @@
<%
def today
Time.now.to_s(:db)
Time.now.utc.to_s(:db)
end
def next_week
1.week.from_now.to_s(:db)
1.week.from_now.utc.to_s(:db)
end
def last_week
1.week.ago.to_s(:db)
1.week.ago.utc.to_s(:db)
end
def two_weeks_hence
2.week.from_now.to_s(:db)
2.week.from_now.utc.to_s(:db)
end
%>

View file

@ -25,7 +25,7 @@ class ProjectControllerTest < TodoContainerControllerTestBase
assert_equal 1, assigns['deferred'].size
t = p.not_done_todos[0]
t.show_from = 1.days.from_now.to_date
t.show_from = 1.days.from_now.utc.to_date
t.save!
get :show, :url_friendly_name => p.url_friendly_name

View file

@ -71,7 +71,9 @@ class TodoControllerTest < Test::Unit::TestCase
#assert_rjs :page, "todo_1", :visual_effect, :highlight, :duration => '1'
t = Todo.find(1)
assert_equal "Call Warren Buffet to find out how much he makes per day", t.description
assert_equal Date.new(2006,11,30), t.due
expected = Date.new(2006,11,30).to_time.utc.to_date
actual = t.due
assert_equal expected, actual, "Expected #{expected.to_s(:db)}, was #{actual.to_s(:db)}"
end

View file

@ -0,0 +1,18 @@
require File.dirname(__FILE__) + '/../test_helper'
class PreferenceTest < Test::Unit::TestCase
fixtures :users, :preferences
def setup
assert_equal "test", ENV['RAILS_ENV']
assert_equal "change-me", Tracks::Config.salt
@admin_user = User.find(1)
@other_user = User.find(2)
end
def test_time_zone
assert_equal 'London', @admin_user.preference.time_zone
assert_equal @admin_user.preference.tz, TimeZone['London']
end
end

View file

@ -102,7 +102,7 @@ class ProjectTest < Test::Unit::TestCase
def test_deferred_todos
assert_equal 1, @timemachine.deferred_todos.size
t = @timemachine.not_done_todos[0]
t.show_from = 1.days.from_now.to_date
t.show_from = 1.days.from_now.utc.to_date
t.save!
assert_equal 2, Project.find(@timemachine.id).deferred_todos.size
end

View file

@ -19,8 +19,8 @@ class TodoTest < Test::Unit::TestCase
assert_equal "Call Bill Gates to find out how much he makes per day", @not_completed1.description
assert_nil @not_completed1.notes
assert @not_completed1.completed? == false
assert_equal 1.week.ago.strftime("%Y-%m-%d %H:%M"), @not_completed1.created_at.strftime("%Y-%m-%d %H:%M")
assert_equal 2.week.from_now.strftime("%Y-%m-%d"), @not_completed1.due.strftime("%Y-%m-%d")
assert_equal 1.week.ago.utc.strftime("%Y-%m-%d %H:%M"), @not_completed1.created_at.strftime("%Y-%m-%d %H:%M")
assert_equal 2.week.from_now.utc.strftime("%Y-%m-%d"), @not_completed1.due.strftime("%Y-%m-%d")
assert_nil @not_completed1.completed_at
assert_equal 1, @not_completed1.user_id
end

View file

@ -1,7 +1,7 @@
require File.dirname(__FILE__) + '/../test_helper'
class UserTest < Test::Unit::TestCase
fixtures :users
fixtures :users, :preferences
def setup
assert_equal "test", ENV['RAILS_ENV']
@ -134,5 +134,9 @@ class UserTest < Test::Unit::TestCase
@other_user.last_name = nil
assert_equal @other_user.login, @other_user.display_name
end
def test_prefs_is_short_for_preference
assert_equal @admin_user.preference, @admin_user.prefs
end
end