mirror of
https://github.com/TracksApp/tracks.git
synced 2026-02-03 06:21:49 +01:00
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:
parent
9a444be3fe
commit
2329cb8e1e
30 changed files with 218 additions and 191 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
|
|
|||
|
|
@ -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] -->
|
||||
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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") %>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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? } } -%>
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
11
tracks/db/migrate/021_add_time_zone_preference.rb
Normal file
11
tracks/db/migrate/021_add_time_zone_preference.rb
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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={})
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};*/
|
||||
};
|
||||
|
|
|
|||
6
tracks/test/fixtures/notes.yml
vendored
6
tracks/test/fixtures/notes.yml
vendored
|
|
@ -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
|
||||
%>
|
||||
|
||||
|
|
|
|||
2
tracks/test/fixtures/preferences.yml
vendored
2
tracks/test/fixtures/preferences.yml
vendored
|
|
@ -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
|
||||
|
|
|
|||
8
tracks/test/fixtures/todos.yml
vendored
8
tracks/test/fixtures/todos.yml
vendored
|
|
@ -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
|
||||
|
||||
%>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
18
tracks/test/unit/preference_test.rb
Normal file
18
tracks/test/unit/preference_test.rb
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue