From 6136efdb7f78bd39b4248708e780569f65be0815 Mon Sep 17 00:00:00 2001 From: lrbalt Date: Thu, 22 May 2008 08:33:15 +0000 Subject: [PATCH 1/5] adds search to tracks. you can search now on todos, projects and notes. This patch was contributed by Jeffrey Gipson. Thanks Jeffrey! git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@853 a4c988fc-2ded-0310-b66e-134b36920a42 --- tracks/app/controllers/search_controller.rb | 27 + tracks/app/controllers/todos_controller.rb | 3 + tracks/app/helpers/search_helper.rb | 3 + tracks/app/helpers/todos_helper.rb | 536 +++++++++--------- tracks/app/models/todo.rb | 11 +- tracks/app/views/layouts/standard.html.erb | 1 + tracks/app/views/notes/_notes.rhtml | 78 +-- tracks/app/views/projects/_project.rhtml | 10 +- .../app/views/projects/_project_listing.rhtml | 10 +- tracks/app/views/search/index.rhtml | 6 + tracks/app/views/search/results.rhtml | 32 ++ tracks/app/views/todos/_todo.html.erb | 3 +- tracks/public/images/system-search.png | Bin 0 -> 935 bytes tracks/public/stylesheets/standard.css | 5 + .../test/functional/todos_controller_test.rb | 4 +- 15 files changed, 407 insertions(+), 322 deletions(-) create mode 100644 tracks/app/controllers/search_controller.rb create mode 100644 tracks/app/helpers/search_helper.rb create mode 100644 tracks/app/views/search/index.rhtml create mode 100644 tracks/app/views/search/results.rhtml create mode 100644 tracks/public/images/system-search.png diff --git a/tracks/app/controllers/search_controller.rb b/tracks/app/controllers/search_controller.rb new file mode 100644 index 00000000..baaa25dd --- /dev/null +++ b/tracks/app/controllers/search_controller.rb @@ -0,0 +1,27 @@ +class SearchController < ApplicationController + + helper :todos, :application, :notes, :projects + + def results + @source_view = params['_source_view'] || 'search' + @page_title = "TRACKS::Search Results for #{params[:search]}" + terms = '%' + params[:search] + '%' + @found_todos = current_user.todos.find(:all, :conditions => ["todos.description LIKE ? OR todos.notes LIKE ?", terms, terms], :include => [:tags, :project, :context]) + @found_projects = current_user.projects.find(:all, :conditions => ["name LIKE ? or description LIKE ?", terms, terms]) + @found_notes = current_user.notes.find(:all, :conditions => ["body LIKE ?", terms]) + + @count = @found_todos.size + @found_projects.size + @found_notes.size + + init_not_done_counts(['project']) + init_project_hidden_todo_counts(['project']) + end + + def index + @page_title = "TRACKS::Search" + end + + def init + @source_view = params['_source_view'] || 'search' + end + +end diff --git a/tracks/app/controllers/todos_controller.rb b/tracks/app/controllers/todos_controller.rb index ffb03d5d..a334e189 100644 --- a/tracks/app/controllers/todos_controller.rb +++ b/tracks/app/controllers/todos_controller.rb @@ -67,6 +67,9 @@ class TodosController < ApplicationController respond_to do |format| format.html { redirect_to :action => "index" } format.m do + @return_path=cookies[:mobile_url] + # todo: use function for this fixed path + @return_path='/mobile' if @return_path.nil? if @saved redirect_to mobile_abbrev_url else diff --git a/tracks/app/helpers/search_helper.rb b/tracks/app/helpers/search_helper.rb new file mode 100644 index 00000000..56867b18 --- /dev/null +++ b/tracks/app/helpers/search_helper.rb @@ -0,0 +1,3 @@ +module SearchHelper + +end diff --git a/tracks/app/helpers/todos_helper.rb b/tracks/app/helpers/todos_helper.rb index d171f746..7b9ca745 100644 --- a/tracks/app/helpers/todos_helper.rb +++ b/tracks/app/helpers/todos_helper.rb @@ -1,268 +1,268 @@ -module TodosHelper - - # #require 'users_controller' Counts the number of incomplete items in the - # specified context - # - def count_items(context) - count = Todo.find_all("done=0 AND context_id=#{context.id}").length - end - - def form_remote_tag_edit_todo( &block ) - form_tag( - todo_path(@todo), { - :method => :put, - :id => dom_id(@todo, 'form'), - :class => dom_id(@todo, 'form') + " inline-form edit_todo_form" }, - &block ) - apply_behavior 'form.edit_todo_form', make_remote_form( - :method => :put, - :before => "this.down('button.positive').startWaiting()", - :loaded => "this.down('button.positive').stopWaiting()", - :condition => "!(this.down('button.positive').isWaiting())"), - :prevent_default => true - end - - def remote_delete_icon - parameters = "_source_view=#{@source_view}" - parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag' - str = link_to( image_tag_for_delete, - todo_path(@todo), :id => "delete_icon_"+@todo.id.to_s, - :class => "icon delete_icon", :title => "delete the action '#{@todo.description}'") - apply_behavior '.item-container a.delete_icon:click', :prevent_default => true do |page| - page.confirming "'Are you sure that you want to ' + this.title + '?'" do - page << "itemContainer = this.up('.item-container'); itemContainer.startWaiting();" - page << remote_to_href(:method => 'delete', :with => "'#{parameters}'", :complete => "itemContainer.stopWaiting();") - end - end - str - end - - def remote_star_icon - str = link_to( image_tag_for_star(@todo), - toggle_star_todo_path(@todo), - :class => "icon star_item", :title => "star the action '#{@todo.description}'") - apply_behavior '.item-container a.star_item:click', - remote_to_href(:method => 'put', :with => "{ _source_view : '#{@source_view}' }"), - :prevent_default => true - str - end - - def remote_edit_icon - parameters = "_source_view=#{@source_view}" - parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag' - if !@todo.completed? - str = link_to( image_tag_for_edit, - edit_todo_path(@todo), - :class => "icon edit_icon") - apply_behavior '.item-container a.edit_icon:click', :prevent_default => true do |page| - page << "Effect.Pulsate(this);" - page << remote_to_href(:method => 'get', :with => "'#{parameters}'") - end - else - str = '' + image_tag("blank.png") + " " - end - str - end - - def remote_toggle_checkbox - str = check_box_tag('item_id', toggle_check_todo_path(@todo), @todo.completed?, :class => 'item-checkbox') - parameters = "_source_view=#{@source_view}" - parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag' - apply_behavior '.item-container input.item-checkbox:click', - remote_function(:url => javascript_variable('this.value'), :method => 'put', - :with => "'#{parameters}'") - str - end - - def date_span - if @todo.completed? - "#{format_date( @todo.completed_at )}" - elsif @todo.deferred? - show_date( @todo.show_from ) - else - due_date( @todo.due ) - end - end - - def tag_list_text - @todo.tags.collect{|t| t.name}.join(', ') - end - - def tag_list - tags_except_starred = @todo.tags.reject{|t| t.name == Todo::STARRED_TAG_NAME} - tag_list = tags_except_starred.collect{|t| "" + link_to(t.name, :controller => "todos", :action => "tag", :id => t.name) + ""}.join('') - "#{tag_list}" - end - - def tag_list_mobile - tags_except_starred = @todo.tags.reject{|t| t.name == Todo::STARRED_TAG_NAME} - # removed the link. TODO: add link to mobile view of tagged actions - tag_list = tags_except_starred.collect{|t| - "" + - link_to(t.name, {:action => "tag", :controller => "todos", :id => t.name+".m"}) + - # link_to(t.name, formatted_tag_path(t, :m)) + - ""}.join('') - "#{tag_list}" - end - - def deferred_due_date - if @todo.deferred? && @todo.due - "(action due on #{format_date(@todo.due)})" - end - end - - def project_and_context_links(parent_container_type, opts = {}) - str = '' - if @todo.completed? - str += @todo.context.name unless opts[:suppress_context] - should_suppress_project = opts[:suppress_project] || @todo.project.nil? - str += ", " unless str.blank? || should_suppress_project - str += @todo.project.name unless should_suppress_project - str = "(#{str})" unless str.blank? - else - if (['project', 'tag', 'stats'].include?(parent_container_type)) - str << item_link_to_context( @todo ) - end - if (['context', 'tickler', 'tag', 'stats'].include?(parent_container_type)) && @todo.project_id - str << item_link_to_project( @todo ) - end - end - return str - end - - # Uses the 'staleness_starts' value from settings.yml (in days) to colour the - # background of the action appropriately according to the age of the creation - # date: - # * l1: created more than 1 x staleness_starts, but < 2 x staleness_starts - # * l2: created more than 2 x staleness_starts, but < 3 x staleness_starts - # * l3: created more than 3 x staleness_starts - # - def staleness_class(item) - if item.due || item.completed? - return "" - elsif item.created_at < user_time - (prefs.staleness_starts * 3).days - return " stale_l3" - elsif item.created_at < user_time - (prefs.staleness_starts * 2).days - return " stale_l2" - elsif item.created_at < user_time - (prefs.staleness_starts).days - return " stale_l1" - else - return "" - end - end - - # Check show_from date in comparison to today's date Flag up date - # appropriately with a 'traffic light' colour code - # - def show_date(d) - if d == nil - return "" - end - - days = days_from_today(d) - - case days - # overdue or due very soon! sound the alarm! - when -1000..-1 - "Scheduled to show " + (days * -1).to_s + " days ago " - when 0 - "Show Today " - when 1 - "Show Tomorrow " - # due 2-7 days away - when 2..7 - if prefs.due_style == Preference.due_styles[:due_on] - "Show on " + d.strftime("%A") + " " - else - "Show in " + days.to_s + " days " - end - # more than a week away - relax - else - "Show in " + days.to_s + " days " - end - end - - def calendar_setup( input_field ) - str = "Calendar.setup({ ifFormat:\"#{prefs.date_format}\"" - str << ",firstDay:#{prefs.week_starts},showOthers:true,range:[2004, 2010]" - str << ",step:1,inputField:\"" + input_field + "\",cache:true,align:\"TR\" })\n" - javascript_tag str - end - - def item_container_id - if source_view_is :project - return "p#{@todo.project_id}" if @todo.active? - return "tickler" if @todo.deferred? - end - return "c#{@todo.context_id}" - end - - def should_show_new_item - - if @todo.project.nil? == false - # do not show new actions that were added to hidden or completed projects - # on home page and context page - return false if source_view_is(:todo) && (@todo.project.hidden? || @todo.project.completed?) - return false if source_view_is(:context) && (@todo.project.hidden? || @todo.project.completed?) - end - - return true if source_view_is(:deferred) && @todo.deferred? - return true if source_view_is(:project) && @todo.project.hidden? && @todo.project_hidden? - return true if source_view_is(:project) && @todo.deferred? - return true if !source_view_is(:deferred) && @todo.active? - return false - end - - def parent_container_type - return 'tickler' if source_view_is :deferred - return 'project' if source_view_is :project - return 'stats' if source_view_is :stats - return 'context' - end - - def empty_container_msg_div_id - return "tickler-empty-nd" if source_view_is(:project) && @todo.deferred? - return "p#{@todo.project_id}empty-nd" if source_view_is :project - return "c#{@todo.context_id}empty-nd" - end - - def project_names_for_autocomplete - array_or_string_for_javascript( ['None'] + @projects.select{ |p| p.active? }.collect{|p| escape_javascript(p.name) } ) - end - - def context_names_for_autocomplete - # #return array_or_string_for_javascript(['Create a new context']) if - # @contexts.empty? - array_or_string_for_javascript( @contexts.collect{|c| escape_javascript(c.name) } ) - end - - def format_ical_notes(notes) - split_notes = notes.split(/\n/) - joined_notes = split_notes.join("\\n") - end - - def formatted_pagination(total) - s = will_paginate(@todos) - (s.gsub /(<\/[^<]+>)/, '\1 ').chomp(' ') - end - - def date_field_tag(name, id, value = nil, options = {}) - text_field_tag name, value, {"size" => 12, "id" => id, "class" => "Date", "onfocus" => "Calendar.setup", "autocomplete" => "off"}.update(options.stringify_keys) - end - - private - - def image_tag_for_delete - image_tag("blank.png", :title =>"Delete action", :class=>"delete_item") - end - - def image_tag_for_edit - image_tag("blank.png", :title =>"Edit action", :class=>"edit_item", :id=> dom_id(@todo, 'edit_icon')) - end - - def image_tag_for_star(todo) - class_str = todo.starred? ? "starred_todo" : "unstarred_todo" - image_tag("blank.png", :title =>"Star action", :class => class_str) - end - -end +module TodosHelper + + # #require 'users_controller' Counts the number of incomplete items in the + # specified context + # + def count_items(context) + count = Todo.find_all("done=0 AND context_id=#{context.id}").length + end + + def form_remote_tag_edit_todo( &block ) + form_tag( + todo_path(@todo), { + :method => :put, + :id => dom_id(@todo, 'form'), + :class => dom_id(@todo, 'form') + " inline-form edit_todo_form" }, + &block ) + apply_behavior 'form.edit_todo_form', make_remote_form( + :method => :put, + :before => "this.down('button.positive').startWaiting()", + :loaded => "this.down('button.positive').stopWaiting()", + :condition => "!(this.down('button.positive').isWaiting())"), + :prevent_default => true + end + + def remote_delete_icon + parameters = "_source_view=#{@source_view}" + parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag' + str = link_to( image_tag_for_delete, + todo_path(@todo), :id => "delete_icon_"+@todo.id.to_s, + :class => "icon delete_icon", :title => "delete the action '#{@todo.description}'") + apply_behavior '.item-container a.delete_icon:click', :prevent_default => true do |page| + page.confirming "'Are you sure that you want to ' + this.title + '?'" do + page << "itemContainer = this.up('.item-container'); itemContainer.startWaiting();" + page << remote_to_href(:method => 'delete', :with => "'#{parameters}'", :complete => "itemContainer.stopWaiting();") + end + end + str + end + + def remote_star_icon + str = link_to( image_tag_for_star(@todo), + toggle_star_todo_path(@todo), + :class => "icon star_item", :title => "star the action '#{@todo.description}'") + apply_behavior '.item-container a.star_item:click', + remote_to_href(:method => 'put', :with => "{ _source_view : '#{@source_view}' }"), + :prevent_default => true + str + end + + def remote_edit_icon + parameters = "_source_view=#{@source_view}" + parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag' + if !@todo.completed? + str = link_to( image_tag_for_edit, + edit_todo_path(@todo), + :class => "icon edit_icon") + apply_behavior '.item-container a.edit_icon:click', :prevent_default => true do |page| + page << "Effect.Pulsate(this);" + page << remote_to_href(:method => 'get', :with => "'#{parameters}'") + end + else + str = '' + image_tag("blank.png") + " " + end + str + end + + def remote_toggle_checkbox + str = check_box_tag('item_id', toggle_check_todo_path(@todo), @todo.completed?, :class => 'item-checkbox') + parameters = "_source_view=#{@source_view}" + parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag' + apply_behavior '.item-container input.item-checkbox:click', + remote_function(:url => javascript_variable('this.value'), :method => 'put', + :with => "'#{parameters}'") + str + end + + def date_span + if @todo.completed? + "#{format_date( @todo.completed_at )}" + elsif @todo.deferred? + show_date( @todo.show_from ) + else + due_date( @todo.due ) + end + end + + def tag_list_text + @todo.tags.collect{|t| t.name}.join(', ') + end + + def tag_list + tags_except_starred = @todo.tags.reject{|t| t.name == Todo::STARRED_TAG_NAME} + tag_list = tags_except_starred.collect{|t| "" + link_to(t.name, :controller => "todos", :action => "tag", :id => t.name) + ""}.join('') + "#{tag_list}" + end + + def tag_list_mobile + tags_except_starred = @todo.tags.reject{|t| t.name == Todo::STARRED_TAG_NAME} + # removed the link. TODO: add link to mobile view of tagged actions + tag_list = tags_except_starred.collect{|t| + "" + + link_to(t.name, {:action => "tag", :controller => "todos", :id => t.name+".m"}) + + # link_to(t.name, formatted_tag_path(t, :m)) + + ""}.join('') + "#{tag_list}" + end + + def deferred_due_date + if @todo.deferred? && @todo.due + "(action due on #{format_date(@todo.due)})" + end + end + + def project_and_context_links(parent_container_type, opts = {}) + str = '' + if @todo.completed? + str += @todo.context.name unless opts[:suppress_context] + should_suppress_project = opts[:suppress_project] || @todo.project.nil? + str += ", " unless str.blank? || should_suppress_project + str += @todo.project.name unless should_suppress_project + str = "(#{str})" unless str.blank? + else + if (['project', 'tag', 'stats', 'search'].include?(parent_container_type)) + str << item_link_to_context( @todo ) + end + if (['context', 'tickler', 'tag', 'stats', 'search'].include?(parent_container_type)) && @todo.project_id + str << item_link_to_project( @todo ) + end + end + return str + end + + # Uses the 'staleness_starts' value from settings.yml (in days) to colour the + # background of the action appropriately according to the age of the creation + # date: + # * l1: created more than 1 x staleness_starts, but < 2 x staleness_starts + # * l2: created more than 2 x staleness_starts, but < 3 x staleness_starts + # * l3: created more than 3 x staleness_starts + # + def staleness_class(item) + if item.due || item.completed? + return "" + elsif item.created_at < user_time - (prefs.staleness_starts * 3).days + return " stale_l3" + elsif item.created_at < user_time - (prefs.staleness_starts * 2).days + return " stale_l2" + elsif item.created_at < user_time - (prefs.staleness_starts).days + return " stale_l1" + else + return "" + end + end + + # Check show_from date in comparison to today's date Flag up date + # appropriately with a 'traffic light' colour code + # + def show_date(d) + if d == nil + return "" + end + + days = days_from_today(d) + + case days + # overdue or due very soon! sound the alarm! + when -1000..-1 + "Scheduled to show " + (days * -1).to_s + " days ago " + when 0 + "Show Today " + when 1 + "Show Tomorrow " + # due 2-7 days away + when 2..7 + if prefs.due_style == Preference.due_styles[:due_on] + "Show on " + d.strftime("%A") + " " + else + "Show in " + days.to_s + " days " + end + # more than a week away - relax + else + "Show in " + days.to_s + " days " + end + end + + def calendar_setup( input_field ) + str = "Calendar.setup({ ifFormat:\"#{prefs.date_format}\"" + str << ",firstDay:#{prefs.week_starts},showOthers:true,range:[2004, 2010]" + str << ",step:1,inputField:\"" + input_field + "\",cache:true,align:\"TR\" })\n" + javascript_tag str + end + + def item_container_id + if source_view_is :project + return "p#{@todo.project_id}" if @todo.active? + return "tickler" if @todo.deferred? + end + return "c#{@todo.context_id}" + end + + def should_show_new_item + + if @todo.project.nil? == false + # do not show new actions that were added to hidden or completed projects + # on home page and context page + return false if source_view_is(:todo) && (@todo.project.hidden? || @todo.project.completed?) + return false if source_view_is(:context) && (@todo.project.hidden? || @todo.project.completed?) + end + + return true if source_view_is(:deferred) && @todo.deferred? + return true if source_view_is(:project) && @todo.project.hidden? && @todo.project_hidden? + return true if source_view_is(:project) && @todo.deferred? + return true if !source_view_is(:deferred) && @todo.active? + return false + end + + def parent_container_type + return 'tickler' if source_view_is :deferred + return 'project' if source_view_is :project + return 'stats' if source_view_is :stats + return 'context' + end + + def empty_container_msg_div_id + return "tickler-empty-nd" if source_view_is(:project) && @todo.deferred? + return "p#{@todo.project_id}empty-nd" if source_view_is :project + return "c#{@todo.context_id}empty-nd" + end + + def project_names_for_autocomplete + array_or_string_for_javascript( ['None'] + @projects.select{ |p| p.active? }.collect{|p| escape_javascript(p.name) } ) + end + + def context_names_for_autocomplete + # #return array_or_string_for_javascript(['Create a new context']) if + # @contexts.empty? + array_or_string_for_javascript( @contexts.collect{|c| escape_javascript(c.name) } ) + end + + def format_ical_notes(notes) + split_notes = notes.split(/\n/) + joined_notes = split_notes.join("\\n") + end + + def formatted_pagination(total) + s = will_paginate(@todos) + (s.gsub /(<\/[^<]+>)/, '\1 ').chomp(' ') + end + + def date_field_tag(name, id, value = nil, options = {}) + text_field_tag name, value, {"size" => 12, "id" => id, "class" => "Date", "onfocus" => "Calendar.setup", "autocomplete" => "off"}.update(options.stringify_keys) + end + + private + + def image_tag_for_delete + image_tag("blank.png", :title =>"Delete action", :class=>"delete_item") + end + + def image_tag_for_edit + image_tag("blank.png", :title =>"Edit action", :class=>"edit_item", :id=> dom_id(@todo, 'edit_icon')) + end + + def image_tag_for_star(todo) + class_str = todo.starred? ? "starred_todo" : "unstarred_todo" + image_tag("blank.png", :title =>"Star action", :class => class_str) + end + +end diff --git a/tracks/app/models/todo.rb b/tracks/app/models/todo.rb index c3754e53..c7a3c38d 100644 --- a/tracks/app/models/todo.rb +++ b/tracks/app/models/todo.rb @@ -8,8 +8,8 @@ class Todo < ActiveRecord::Base acts_as_state_machine :initial => :active, :column => 'state' - # when entering active state, also remove completed_at date. - # Looks like :exit of state completed is not run, see #679 + # when entering active state, also remove completed_at date. Looks like :exit + # of state completed is not run, see #679 state :active, :enter => Proc.new { |t| t[:show_from], t.completed_at = nil, nil } state :project_hidden state :completed, :enter => Proc.new { |t| t.completed_at = Time.now.utc }, :exit => Proc.new { |t| t.completed_at = nil } @@ -38,8 +38,8 @@ class Todo < ActiveRecord::Base attr_protected :user - # Description field can't be empty, and must be < 100 bytes - # Notes must be < 60,000 bytes (65,000 actually, but I'm being cautious) + # Description field can't be empty, and must be < 100 bytes Notes must be < + # 60,000 bytes (65,000 actually, but I'm being cautious) validates_presence_of :description validates_length_of :description, :maximum => 100 validates_length_of :notes, :maximum => 60000, :allow_nil => true @@ -91,7 +91,8 @@ class Todo < ActiveRecord::Base alias_method :original_run_initial_state_actions, :run_initial_state_actions def run_initial_state_actions - #only run the initial state actions if the standard initial state hasn't been changed + # only run the initial state actions if the standard initial state hasn't + # been changed if self.class.initial_state.to_sym == current_state original_run_initial_state_actions end diff --git a/tracks/app/views/layouts/standard.html.erb b/tracks/app/views/layouts/standard.html.erb index d0f0e14e..b1535484 100644 --- a/tracks/app/views/layouts/standard.html.erb +++ b/tracks/app/views/layouts/standard.html.erb @@ -59,6 +59,7 @@ window.onload=function(){
  • <%= navigation_link(image_tag("feed-icon.png", :size => "16X16", :border => 0), {:controller => "feedlist", :action => "index"}, :title => "See a list of available feeds" ) %>
  • <%= navigation_link(image_tag("menustar.gif", :size => "16X16", :border => 0), tag_path("starred"), :title => "See your starred actions" ) %>
  • <%= navigation_link(image_tag("stats.gif", :size => "16X16", :border => 0), {:controller => "stats", :action => "index"}, :title => "See your statistics" ) %>
  • +
  • <%= navigation_link(image_tag("system-search.png", :size => "16X16", :border => 0), {:controller => "search", :action => "index"}, :title => "Search All Items" ) %>
  • diff --git a/tracks/app/views/notes/_notes.rhtml b/tracks/app/views/notes/_notes.rhtml index 2d4c3a1a..c99812fc 100644 --- a/tracks/app/views/notes/_notes.rhtml +++ b/tracks/app/views/notes/_notes.rhtml @@ -1,39 +1,39 @@ -<% note = notes -%> -
    -

    <%= link_to("Note #{note.id}", note_path(note), :title => "Show note #{note.id}" ) %>

    -
    - <%= sanitize(textilize(note.body)) %> - - -
    - - -
    -<% note = nil -%> +<% note = notes -%> +
    +

    <%= link_to("Note #{note.id}", note_path(note), :title => "Show note #{note.id}" ) %>

    +
    + <%= sanitize(textilize(note.body)) %> + + +
    + + +
    +<% note = nil -%> diff --git a/tracks/app/views/projects/_project.rhtml b/tracks/app/views/projects/_project.rhtml index e027e2da..14f36f9b 100644 --- a/tracks/app/views/projects/_project.rhtml +++ b/tracks/app/views/projects/_project.rhtml @@ -8,13 +8,13 @@ <%= project.name %> <%= in_place_editor 'project_name_in_place_editor', { :url => { :controller => 'projects', :action => 'update', :id => project.id, :field => 'name', :wants_render => false, :escape => false} , :options=>"{method:'put'}" } %> - <% unless @project.description.blank? -%> -
    <%= sanitize(@project.description) %>
    + <% unless project.description.blank? -%> +
    <%= sanitize(project.description) %>
    <% end -%> - <% if @project.completed? -%> + <% if project.completed? -%>

    Project has been marked as completed

    - <% elsif @project.completed? -%> + <% elsif project.completed? -%>

    Project has been marked as hidden

    <% end -%>
    @@ -23,4 +23,4 @@
    <%= render :partial => "todos/todo", :collection => @not_done, :locals => { :parent_container_type => "project" } %> - + \ No newline at end of file diff --git a/tracks/app/views/projects/_project_listing.rhtml b/tracks/app/views/projects/_project_listing.rhtml index dfe0dd41..72f67071 100644 --- a/tracks/app/views/projects/_project_listing.rhtml +++ b/tracks/app/views/projects/_project_listing.rhtml @@ -1,11 +1,15 @@ <% project = project_listing + suppress_drag_handle ||= false + suppress_edit_button ||= false @project_listing_zindex = @project_listing_zindex.nil? ? 200 : @project_listing_zindex - 1 -%>
    " class="list" style="z-index:<%= @project_listing_zindex %>">
    -
    + <% unless suppress_drag_handle -%> +
    DRAG -
    +
    + <% end -%>
    <%= link_to_project( project ) %><%= " (" + count_undone_todos_and_notes_phrase(project,"actions") + ")" %>
    @@ -22,12 +26,14 @@ page << remote_to_href(:method => 'delete') end end -%> + <% unless suppress_edit_button -%> <%= image_tag( "blank.png", :title => "Edit project", :class=>"edit_item") %> <%= apply_behavior 'a.edit_project_button:click', { :prevent_default => true, :external => true } do |page, element| element.up('div.project').start_waiting page << remote_to_href(:method => 'get') end -%> + <% end -%>
    diff --git a/tracks/app/views/search/index.rhtml b/tracks/app/views/search/index.rhtml new file mode 100644 index 00000000..7065746b --- /dev/null +++ b/tracks/app/views/search/index.rhtml @@ -0,0 +1,6 @@ + diff --git a/tracks/app/views/search/results.rhtml b/tracks/app/views/search/results.rhtml new file mode 100644 index 00000000..679360c5 --- /dev/null +++ b/tracks/app/views/search/results.rhtml @@ -0,0 +1,32 @@ +
    + <% if @count == 0 -%> +

    Your search yielded no results.

    + <% else -%> + <% source_view_is = :search %> + <% parent_container_type = 'search' %> + <% if not @found_todos.empty? -%> +
    +

    <%= @found_todos.size %>Todos matching query

    + <%= render :partial => "todos/todo", :collection => @found_todos, :locals => { :parent_container_type => 'search', :suppress_context => false, :suppress_project => false, :suppress_edit_button => true } %> +
    + <% end -%> + + <% if not @found_projects.empty? -%> +
    +

    <%= @found_projects.size %>Projects matching query

    + <%= render :partial => "projects/project_listing", :collection => @found_projects, :locals => { :suppress_drag_handle => true, :suppress_edit_button => true } %> +
    + <% end -%> + + <% if not @found_notes.empty? -%> +
    +

    <%= @found_notes.size %>Notes matching query

    + <% for notes in @found_notes -%> +
    + <%= render :partial => "notes/notes_summary", :object => notes %> +
    + <% end -%> +
    + <% end -%> + <% end -%> +
    diff --git a/tracks/app/views/todos/_todo.html.erb b/tracks/app/views/todos/_todo.html.erb index 6f8579c2..30090ab4 100644 --- a/tracks/app/views/todos/_todo.html.erb +++ b/tracks/app/views/todos/_todo.html.erb @@ -2,11 +2,12 @@ @todo = todo suppress_context ||= false suppress_project ||= false + suppress_edit_button ||= false %>
    <%= remote_delete_icon %> - <%= remote_edit_icon %> + <%= remote_edit_icon unless suppress_edit_button %> <%= remote_star_icon %> <%= remote_toggle_checkbox unless source_view_is :deferred %>
    diff --git a/tracks/public/images/system-search.png b/tracks/public/images/system-search.png new file mode 100644 index 0000000000000000000000000000000000000000..fd7f0b07a558cb6d59af96bebb672bf1abe96c88 GIT binary patch literal 935 zcmV;Y16cftP)&ujZZ2vcpl1 zMZ@GK2apA{PG?ddXEM`!?RHyZ=kcza{{|ocz_G78)~3_xTfzOGVc*@!;z&{~D4M34 z#HCy|oAJK^O5@u;x%xm;z_nWd04$M+pY+%HrNI}599Zr)1O{&1Fr9gQ zRx^nN(=^?Ylb_Xc3crTMTm|}8W6tGCdm-gHU zoivEbfP*V-h@Y#f29hN4c>od3S|m}D80SwWrl%O%n5zs-y=aEVV!4n`6c;!WFs{rR zhNug$8$G1gD4`4AaS<H7=eg9>uBL$90I_nW$UopHtf^aCQMJwQhI406Q(#?y zO-@ZpM5e?TYiVd$*M}u5U8hd09vd6~!{hc8oX&FDU*~sLS6AD5dV3x{dHP7z^Tsz$ zm;I-vElqH5_&#iSZzKKk>qUmIhNJ7$iG2Xj914Xt0)Xc8`7QxKZ+qL(^TA-S6B++< zPs?7gTFc=3v)=)}CSYu?u#}a#&H(^gTU%RH&GN(C?nC&$dI>wJW|L@7q6Gi|002ov JPDHLkV1n1##MS@+ literal 0 HcmV?d00001 diff --git a/tracks/public/stylesheets/standard.css b/tracks/public/stylesheets/standard.css index 79c26892..54105f79 100644 --- a/tracks/public/stylesheets/standard.css +++ b/tracks/public/stylesheets/standard.css @@ -609,6 +609,11 @@ div#list-active-projects, div#list-hidden-projects, div#list-completed-projects, .project-state-group h2 { margin:20px 0px 8px 13px; } + +.search-result-group h2 { + margin:20px 0px 8px 13px +} + div.alpha_sort { margin-top:-20px; float:right; diff --git a/tracks/test/functional/todos_controller_test.rb b/tracks/test/functional/todos_controller_test.rb index f623421f..8c2de6e2 100644 --- a/tracks/test/functional/todos_controller_test.rb +++ b/tracks/test/functional/todos_controller_test.rb @@ -346,8 +346,8 @@ class TodosControllerTest < Test::Rails::TestCase post :create, {"format"=>"m", "todo"=>{"context_id"=>"2", "due(1i)"=>"2007", "due(2i)"=>"1", "due(3i)"=>"2", "show_from(1i)"=>"", "show_from(2i)"=>"", "show_from(3i)"=>"", - "project_id"=>"1", - "notes"=>"test notes", "state"=>"0"}} + "project_id"=>"1", + "notes"=>"test notes", "state"=>"0"}, "tag_list"=>"test, test2"} assert_template 'todos/new' end From f28fdc05a56599e00d3356b72c4b0bbb24207bc0 Mon Sep 17 00:00:00 2001 From: lrbalt Date: Thu, 22 May 2008 08:41:19 +0000 Subject: [PATCH 2/5] updates the compressed stylesheet because of changed of last commit git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@854 a4c988fc-2ded-0310-b66e-134b36920a42 --- tracks/public/stylesheets/tracks_853.css | 275 +++++++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 tracks/public/stylesheets/tracks_853.css diff --git a/tracks/public/stylesheets/tracks_853.css b/tracks/public/stylesheets/tracks_853.css new file mode 100644 index 00000000..d5ab3b95 --- /dev/null +++ b/tracks/public/stylesheets/tracks_853.css @@ -0,0 +1,275 @@ +body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td {margin:0; padding:0} +table {border-collapse:collapse; border-spacing:0} +fieldset,img {border:0} +address,caption,cite,code,dfn,em,strong,th,var {font-style:normal; font-weight:normal} +ol,ul {list-style:none} +caption,th {text-align:left} +h1,h2,h3,h4,h5,h6 {font-size:100%; font-weight:normal} +q:before,q:after {content:''} +abbr,acronym {border:0} +body {font-family: "Lucida Grande", Verdana, Geneva, Arial, sans-serif; font-size: 80%; padding: 0px 10px; margin: 0px; background: #eee} +p {padding: 2px; font-size: 92%; line-height: 140%} +a, a:link, a:active, a:visited {color: #cc3334; text-decoration: none; padding-left: 1px; padding-right: 1px} +a:hover {color: #fff; background-color: #cc3334} +h1 {font-size: 304%; font-weight: bold} +h2 {font-size: 148%; font-weight: bold} +h3 {font-size: 129%; font-weight: bold} +img.edit_item {background-image: url(../images/edit_off.png); background-repeat: no-repeat; border: none;} +a:hover img.edit_item {background-image: url(../images/edit_on.png); background-color: transparent; background-repeat: no-repeat; border: none;} +img.delete_item {background-image: url(../images/delete_off.png); background-repeat: no-repeat; border: none;} +a:hover img.delete_item {background-image: url(../images/delete_on.png);background-color: transparent;background-repeat: no-repeat; border: none;} +img.starred_todo {background-image: url(../images/staricons.png); background-repeat: no-repeat; border:none; background-position: 0px 0px;} +a:hover img.starred_todo {background-image: url(../images/staricons.png); background-repeat: no-repeat; border:none; background-position: -16px 0px;} +img.unstarred_todo {background-image: url(../images/staricons.png); background-repeat: no-repeat; border:none; background-position: -32px 0px;} +a:hover img.unstarred_todo {background-image: url(../images/staricons.png); background-repeat: no-repeat; border:none; background-position: -48px 0px;} +a.to_top {background: transparent url(../images/top_off.png) no-repeat;} +a.to_top:hover {background: transparent url(../images/top_on.png) no-repeat;} +a.up {background: transparent url(../images/up_off.png) no-repeat;} +a.up:hover {background: transparent url(../images/up_on.png) no-repeat;} +a.down {background: transparent url(../images/down_off.png) no-repeat;} +a.down:hover {background: transparent url(../images/down_on.png) no-repeat;} +a.to_bottom {background: transparent url(../images/bottom_off.png) no-repeat;} +a.to_bottom:hover {background: transparent url(../images/bottom_on.png) no-repeat;} +a.show_notes, a.link_to_notes {background-image: url(../images/notes_off.png); background-repeat: no-repeat; padding: 1px; background-color: transparent;} +a.show_notes:hover, a.link_to_notes:hover {background-image: url(../images/notes_on.png); background-repeat: no-repeat; padding: 1px; background-color: transparent;} +#content {margin-top: 90px} +#display_box {float: left; width: 55%; margin: 0px 10px 50px 15px} +#single_box {width: 60%; margin: 80px auto} +#full_width_display {float: left; width: 95%; margin: 0px 15px 90px 15px} +#display_box_projects {float: left; width: 95%; margin: 0px 15px 90px 15px} +#navcontainer {position: fixed; top: 48px; left: 0px} +#navlist {margin: 0; padding: 0 0 20px 5px} +#navlist ul, #navlist li {margin: 0; padding: 0; display: inline; list-style-type: none} +#navlist a:link, #navlist a:visited {float: left; line-height: 14px; font-weight: bold; margin: 0 10px 4px 10px; text-decoration: none; color: #eee} +#navlist a:link#current, #navlist a:visited#current, #navlist a:hover {border-bottom: 4px solid #CCC; padding-bottom: 2px; background: transparent; color: #CCC} +#navlist a:hover {color: #CCC} +#topbar {position: fixed; top: 0px; left: 0px; height: 68px; margin-bottom: 20px; clear: both; background-color: #000; filter: alpha(opacity=75); -moz-opacity: .75; opacity: .75; color: #eee; width: 100%; z-index:1100} +body.stats #topbar {filter: alpha(opacity=100); -moz-opacity: 1; opacity: 1} +#date {float: left; width: 45%; padding-left: 15px; margin-top: 15px; margin-bottom: 5px; white-space: nowrap} +#date h1 {font-size: 152%} +#minilinks {text-align: right; position: fixed; right: 15px; top: 10px; font-size: 0.9em} +.container {padding: 0px 5px 0px 5px; border: 1px solid #999; margin: 0px 0px 15px 0px; background: #fff} +.completed {background: #eee} +.container h2 {background: #ccc; padding: 5px; margin-top: 0px; margin-left: -5px; margin-right: -5px; margin-bottom: 0px; color: #666; position:left} +.container_toggle img {height:20px; width:20px; border:0px} +h2 a, h2 a:link, h2 a:active, h2 a:visited {color: #666; text-decoration: none} +h2 a:hover {color: #cc3334; background-color: transparent; text-decoration: none} +div#input_box {margin: 0px 15px 0px 58%; padding: 0px 15px 0px 0px} +#input_box h2 {color: #999} +#input_box ul {list-style-type: circle; font-size: 0.9em;} +.show_from_input, .due_input, .project_input, .context_input {float:left} +.box {float: left; width: 20px} +div.item-container {padding: 2px 0px; line-height:20px; clear: both} +a.icon {float: left; vertical-align: middle; background-color: transparent} +input.item-checkbox {float: left; margin-left: 10px; vertical-align: middle} +.description {margin-left: 85px; position:relative } +.stale_l1, .stale_l2, .stale_l3 {margin-left: 82px; padding-left: 3px} +.stale_l1 {background: #ffC} +.tools {margin-left: 25px; width: 40px; border-top: 1px solid #999} +#footer {clear: both; font-size: 85%; text-align: center; color: #999; margin: 20px 20px 5px 20px; padding: 0px} +.todo_notes {margin: 5px; padding: 3px; border: 1px solid #F5ED59; background: #FAF6AE; color: #666666} +.todo_notes p, .todo_notes li {padding: 1px; margin: 0px; font-size: 12px} +.todo_notes ul, .note_wrapper ul {list-style-type: disc; margin-left:20px} +.todo_notes ol {list-style-type: decimal; margin-left:20px} +div.note_wrapper {margin: 3px; padding: 2px} +div.note_wrapper p {display: inline} +div.note_footer {border-top: 1px solid #999; padding-top: 3px; font-style: italic; font-size: 0.9em; color: #666} +div.note_footer a, div.note_footer a:hover {border-top: none; padding-top: 0px; vertical-align: middle; background-color: transparent} +div.add_note_link {margin-top:12px; float: right} +div#project_status > div {padding: 10px} +#project_status span {margin-right:5px; background-color:white} +#project_status .active_state {font-weight:bold} +div#default_context > div{ padding:10px} +a.footer_link {color: #cc3334; font-style: normal;} +a.footer_link:hover {color: #fff; background-color: #cc3334 !important;} +span.tag {font-size: 0.8em; background-color: #CCE7FF; color: #000; padding: 1px; margin-right: 2px} +span.tag a, span.tag a:link, span.tag a:active, span.tag a:visited {color: #000} +span.tag a:hover {background-color: #99CCFF; color: #333} +div#message_holder {position: absolute; z-index: 100; left: 60%; top: 30px; right: 0px; margin: 0px} +h4.alert {font-size: 1em; margin: 0px; padding: 5px; text-align: center} +h4.warning {border: 1px solid #ED2E38; background-color: #F6979C; color: #000} +h4.error {color:#fff; background:#c00} +h4.notice {border: 1px solid #007E00; background-color: #c2ffc2; color: #007E00} +.project_completed {border: 1px solid #007E00; background-color: #c2ffc2; padding: 5px; color: #007E00; text-align: center} +.red {color: #fff; background: #f00; padding: 1px; font-size: 85%} +.amber {color: #fff; background: #ff6600; padding: 1px; font-size: 85%} +.orange {color: #fff; background: #FFA500; padding: 1px; font-size: 85%} +.green {color: #fff; background: #33cc00; padding: 1px; font-size: 85%} +.grey {color: #fff; background: #999; padding: 2px; font-size: 85%} +.info {color: #fff; background: #CCC; border: 1px solid #999; padding: 5px; text-align: center} +.highlight {background: #ffC; padding: 2px} +.stale_l1 {background: #ffC} +.stale_l2 {background: #ff6} +.stale_l3 {background: #ff0} +.badge {color: #fff; background: #f00; padding: 3px 5px; font-size: 12pt; margin: 10px 10px 0px 0px; height:26px} +ul {list-style-type: none} +#sidebar h3 {margin-top:15px; margin-bottom:5px} +#sidebar ul {margin-left: auto; list-style-position: inside} +li {font-size: 1.1em; padding: 3px 0px} +#sidebar li {padding: auto} +#sidebar .integrations-link {margin-top:10px; padding-top:10px; font-size: 0.8em} +.sortable_row {background: #fff; _background: transparent; padding: 4px 4px 4px 8px; margin: 2px 2px; border: 1px solid #ccc} +.edit-form {background: #ccc; padding: 0 10px; border-top: 1px solid #999; border-bottom: 1px solid #999; position:relative} +.label {text-align: right} +input {vertical-align: middle} +img.position, a:hover img.position {text-align: left; vertical-align: middle; background-color: transparent} +.data {text-align: left; margin-left: 20px; float: left} +div.buttons, div.buttons a, div.buttons a:hover {text-align: right; margin-right: 0px; vertical-align: middle; background-color: transparent} +div#list-active-projects, div#list-hidden-projects, div#list-completed-projects, div#list-contexts, div#projects-empty-nd {clear:right; border: 1px solid #999} +.project-state-group h2 {margin:20px 0px 8px 13px} +.search-result-group h2 {margin:20px 0px 8px 13px } +div.alpha_sort {margin-top:-20px; float:right} +.container td {border: none; padding-bottom: 5px} +.container form {border: none} +div.project_description {background: #eee; padding: 5px; margin-top: 0px; margin-left: -5px; margin-right: -5px; color: #666; font-style: italic; font-size: 12px; font-weight: normal} +#project-next-prev {text-align:right} +form {border: 1px solid #CCC; padding: 10px; margin: 0px} +.inline-form {border: none; padding: 3px} +.inline-form table {padding-right: 3px} +.inline-form table, .inline-form textarea#item_notes, .inline-form input#item_description {width: 100%} +.inline-form table td.label {width: 13ex} +#todo_new_action_container, #project_new_project_container, #context_new_container {background: #ddd; width: 270px; padding: 5px 10px; background-color: #000; filter: alpha(opacity=75); -moz-opacity: .75; opacity: .75; color: #eee} +#project_new_project_filler {padding-top: 50px} +#todo_new_action_container input, #todo_new_action_container textarea, #project_new_project_container input, #project_new_project_container textarea, #context_new_container input {width: 100%} +input#go_to_project, input#context_hide {width: 5%} +#todo_new_action_container .show_from_input, #todo_new_action_container .due_input {width: 45%} +#todo_new_action_container .show_from_input {float: right} +#todo-form-new-action .submit_box, #project_form .submit_box, #context_form .submit_box {height: 25px; padding: 5px 0; text-align: center; clear: right} +.edit_todo_form .submit_box {height: 25px; padding: 5px 0; text-align: center; clear: right} +.edit_todo_form input, .edit_todo_form textarea {width:100%} +.edit_todo_form .tag_list_label {clear:both} +.edit_todo_form .due_input, .edit_todo_form .show_from_input, .edit_todo_form .project_input, .edit_todo_form .context_input {width:48%} +.edit_todo_form .show_from_input, .edit_todo_form .context_input {float: right} +.edit_todo_form .submit_box input {width:120px} +.hide_form {text-align:right} +#todo-form-new-action label, .edit_todo_form label {display: block; padding-bottom: 3px} +form.button-to {border: none; padding: 0px; margin: 0px} +label {font-weight: bold; padding: 0px 0px} +input, select, textarea {margin: 0px 0px 5px 0px} +.feed {font-family: verdana, sans-serif; font-size: 10px; font-weight:bold; text-decoration:none; color: white; background-color: #F60; border:1px solid; border-color: #FC9 #630 #330 #F96; padding:0px 3px 0px 3px; margin:0px} +.position {float: left; margin-top:2px} +.handle {color: #fff; background: #000; padding: 2px; font-size: 92%; cursor: move} +div.message {margin: 5px 0px; background: #FAF4B5; padding: 2px} +.message p {margin: 0px; padding: 0px; text-align: center; font-size: 1em; color: #666} +.fieldWithErrors {padding: 2px; background-color: red; display: table} +#errorExplanation {border: 2px solid #ff0000; padding: 7px; padding-bottom: 12px; margin: 10px auto 20px auto; background-color: #f0f0f0} +#errorExplanation h2 {text-align: left; font-weight: bold; padding: 5px 5px 5px 15px; font-size: 12px; margin: -7px; background-color: #c00; color: #fff} +#errorExplanation > p {color: #333; margin-top: 5px; margin-bottom: 0; padding: 5px} +#errorExplanation ul li {font-size: 1em; list-style-type: disc; list-style-position: inside; margin-left:7px; color: #333} +ul#prefs {list-style-type: disc; margin-left: 15px;} +#token_area, #authentication_area {text-align:center; margin-top:20px; margin-bottom:10px} +#token_area .description{ font-weight:bold} +#token_area form {width:100%; text-align:center} +.prefscontainer .actions {text-align:center; margin-bottom:20px} +.authtype_container .actions {margin-top:20px; margin-bottom:20px} +#feedlegend {padding: 2px; border: 1px solid #CCC; background-color: #D2D3D6; color: #666; padding: 5px 20px; text-align: left} +#feedlegend h3, #feedlegend dl, #feedlegend dt, #feedlegend dd {display: inline} +#feedlegend dt {margin-left: 15px} +#feedlegend dd {margin-left: 3px} +#feedlegend p {margin-bottom: 0px} +#feeds img.rss-icon {margin-bottom: -4px} +#feeds li {font-size:13px; font-family: "Lucida Grande", Verdana, Geneva, Arial, sans-serif} +#feeds li h4 {margin-top: 12px; margin-bottom: 4px; font-weight: normal; font-style:oblique} +input.open_id {background: url(../images/open-id-login-bg.gif) no-repeat; background-color: #fff; background-position: 0 50%; color: #000; padding-left: 18px; width:182px} +div.page_name_auto_complete {width: 100%; background: #fff; display: inline; z-index: 100} +div.page_name_auto_complete ul {border: 1px solid #888; margin: 0; padding: 0; width: 100%; list-style-type: none} +div.page_name_auto_complete ul li {margin: 0; padding: 2px; font-weight:bold; list-style-type: none; color: #000} +div.page_name_auto_complete ul li.selected {background-color: #ffb} +div.page_name_auto_complete ul strong.highlight {color: #800; margin: 0; padding: 0} +table.next_actions td {padding:5px 3px 2px 0px} +table.users_table {width: 100%; text-align: center; border: 1px solid #666; background-color: #fff; border-spacing: 0px} +.users_table th {color: #fff; background-color: #000;} +.users_table td {border: none;} +table.export_table {border: 1px solid #666; background-color: #fff; border-spacing: 0px} +.export_table th {color: #fff; background-color: #000;} +.export_table td {border: 1px; padding: 5px 0px 5px 5px;} +.widgets a, .widgets button{ display:block; float: left; margin:0px 7px 0 0; background-color:#f5f5f5; border:1px solid #dedede; border-top:1px solid #eee; border-left:1px solid #eee; font-family:"Lucida Grande", Verdana, Geneva, Arial, sans-serif; font-size:80%; line-height:100%; text-decoration:none; font-weight:bold; color:#565656; cursor:pointer; padding:3px 5px 7px 5px} +.widgets button{ width:auto; overflow:visible; padding:3px 5px 5px 5px} +.widgets button[type]{ padding:3px 5px 4px 5px; line-height:15px} +.widgets button img, .widgets a img{ margin:0 3px -3px 0 !important; padding:0; border:none; width:16px; height:16px} +button:hover, .widgets a:hover{ background-color:#dff4ff; border:1px solid #c2e1ef; color:#336699} +.widgets a:active{ background-color:#6299c5; border:1px solid #6299c5; color:#fff} +button.positive, .widgets a.positive{ color: #498111} +.widgets a.positive:hover, button.positive:hover{ background-color:#E6EFC2; border:1px solid #C6D880; color:#529214} +.widgets a.positive:active{ background-color:#529214; border:1px solid #529214; color:#fff} +.widgets a.negative, button.negative{ color:#d12f19} +.widgets a.negative:hover, button.negative:hover{ background:#fbe3e4; border:1px solid #fbc2c4; color:#d12f19} +.widgets a.negative:active{ background-color:#d12f19; border:1px solid #d12f19; color:#fff} +.tracks__waiting {background-image:url('../images/waiting.gif'); background-repeat:no-repeat; background-position:center center; background-color:white} +.bigWaiting {background-image:url('../images/bigWaiting.gif'); background-repeat:no-repeat; background-position:center 20%; background-color:white} +.blackWaiting {background-image:url('../images/blackWaiting.gif'); background-repeat:no-repeat; background-position:center center; background-color:black} +.bigBlackWaiting {background-image:url('../images/bigBlackWaiting.gif'); background-repeat:no-repeat; background-position:center center; background-color:black} +.stats_content .open-flash-chart, .stats_content .stats_module {float: left; width: 450px; margin-right:20px; padding-bottom:20px} +.stats_content h2 {clear:both; margin-top:15px; margin-bottom:15px} +body.integrations h2 {margin-top:40px; padding-top:20px; margin-bottom:10px; border-top:1px solid #ccc} +body.integrations p, body.integrations li {font-size:1.0em} +body.integrations li {list-style-type: disc; list-style-position: inside; margin-left:30px} +body.integrations textarea {margin:10px; padding:3px; width:80%; background-color:#ddd} +div.calendar {position: relative} +.calendar, .calendar table {border: 1px solid #556; font-size: 11px; color: #000; cursor: default; background: #eef; z-index: 110; font-family: tahoma,verdana,sans-serif} +.calendar .button {text-align: center; padding: 2px} +.calendar .nav {background: #778 url(../images/menuarrow.gif) no-repeat 100% 100%} +.calendar thead .title {font-weight: bold; text-align: center; background: #fff; color: #000; padding: 2px} +.calendar thead .headrow {background: #778; color: #fff} +.calendar thead .daynames {background: #bdf} +.calendar thead .name {border-bottom: 1px solid #556; padding: 2px; text-align: center; color: #000} +.calendar thead .weekend {color: #a66} +.calendar thead .hilite {background-color: #aaf; color: #000; border: 1px solid #04f; padding: 1px} +.calendar thead .active {background-color: #77c; padding: 2px 0px 0px 2px} +.calendar tbody .day {width: 2em; color: #456; text-align: right; padding: 2px 4px 2px 2px} +.calendar tbody .day.othermonth {font-size: 80%; color: #bbb} +.calendar tbody .day.othermonth.oweekend {color: #fbb} +.calendar table .wn {padding: 2px 3px 2px 2px; border-right: 1px solid #000; background: #bdf} +.calendar tbody .rowhilite td {background: #def} +.calendar tbody .rowhilite td.wn {background: #eef} +.calendar tbody td.hilite {background: #def; padding: 1px 3px 1px 1px; border: 1px solid #bbb} +.calendar tbody td.active {background: #cde; padding: 2px 2px 0px 2px} +.calendar tbody td.selected {font-weight: bold; border: 1px solid #000; padding: 1px 3px 1px 1px; background: #fff; color: #000} +.calendar tbody td.weekend {color: #a66} +.calendar tbody td.today {font-weight: bold; color: #00f} +.calendar tbody .disabled {color: #999} +.calendar tbody .emptycell {visibility: hidden} +.calendar tbody .emptyrow {display: none} +.calendar tfoot .footrow {text-align: center; background: #556; color: #fff} +.calendar tfoot .ttip {background: #fff; color: #445; border-top: 1px solid #556; padding: 1px} +.calendar tfoot .hilite {background: #aaf; border: 1px solid #04f; color: #000; padding: 1px} +.calendar tfoot .active {background: #77c; padding: 2px 0px 0px 2px} +.calendar .combo {position: absolute; display: none; top: 0px; left: 0px; width: 4em; cursor: default; border: 1px solid #655; background: #def; color: #000; font-size: 90%; z-index: 100} +.calendar .combo .label, .calendar .combo .label-IEfix {text-align: center; padding: 1px} +.calendar .combo .label-IEfix {width: 4em} +.calendar .combo .hilite {background: #acf} +.calendar .combo .active {border-top: 1px solid #46a; border-bottom: 1px solid #46a; background: #eef; font-weight: bold} +.calendar td.time {border-top: 1px solid #000; padding: 1px 0px; text-align: center; background-color: #f4f0e8} +.calendar td.time .hour, .calendar td.time .minute, .calendar td.time .ampm {padding: 0px 3px 0px 4px; border: 1px solid #889; font-weight: bold; background-color: #fff} +.calendar td.time .ampm {text-align: center} +.calendar td.time .colon {padding: 0px 2px 0px 3px; font-weight: bold} +.calendar td.time span.hilite {border-color: #000; background-color: #667; color: #fff} +.calendar td.time span.active {border-color: #f00; background-color: #000; color: #0f0} +b.niftycorners,b.niftyfill{display:block} +b.niftycorners *{display:block;height: 1px;line-height:1px;font-size: 1px; overflow:hidden;border-style:solid;border-width: 0 1px} +b.r1{margin: 0 3px;border-width: 0 2px} +b.r2{margin: 0 2px} +b.r3{margin: 0 1px} +b.r4{height: 2px} +b.rb1{margin: 0 8px;border-width:0 2px} +b.rb2{margin: 0 6px;border-width:0 2px} +b.rb3{margin: 0 5px} +b.rb4{margin: 0 4px} +b.rb5{margin: 0 3px} +b.rb6{margin: 0 2px} +b.rb7{margin: 0 1px;height:2px} +b.rb8{margin: 0;height:2px} +b.rs1{margin: 0 1px} +b.t1{border-width: 0 5px} +b.t2{border-width: 0 3px} +b.t3{border-width: 0 2px} +b.t4{height: 2px} +b.tb1{border-width: 0 10px} +b.tb2{border-width: 0 8px} +b.tb3{border-width: 0 6px} +b.tb4{border-width: 0 5px} +b.tb5{border-width: 0 4px} +b.tb6{border-width: 0 3px} +b.tb7{border-width: 0 2px;height:2px} +b.tb8{border-width: 0 1px;height:2px} +b.ts1{border-width: 0 2px} \ No newline at end of file From 1ebb6406ac5570412d2e5cbeb54368605461c3b7 Mon Sep 17 00:00:00 2001 From: lrbalt Date: Fri, 23 May 2008 13:51:17 +0000 Subject: [PATCH 3/5] adds a search textbox in the menu at top-right git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@855 a4c988fc-2ded-0310-b66e-134b36920a42 --- tracks/app/views/layouts/standard.html.erb | 13 +++++++++---- tracks/public/stylesheets/standard.css | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/tracks/app/views/layouts/standard.html.erb b/tracks/app/views/layouts/standard.html.erb index b1535484..92e7bd1a 100644 --- a/tracks/app/views/layouts/standard.html.erb +++ b/tracks/app/views/layouts/standard.html.erb @@ -35,12 +35,18 @@ window.onload=function(){ <%= user_time.strftime(@prefs.title_date_format) %>
    -