mirror of
https://github.com/TracksApp/tracks.git
synced 2026-01-10 11:18:51 +01:00
Implemented a feature that give a project and optional default context. When set,
this context will be pre-populated when creating an action from the project's page. When creating an action from the home page, the context will be auto-selected when the project is selected if the context field has not yet been entered. This implementation is a combination of the great patch submitted by James Kebinger (thanks James!) and some of my modifications and additions. Don't forget to rake db:migrate. Fixes #162, originally suggested by Rolf one year ago! Also in this commit: * Tweaked selenium tags test * Tweaked formatting of next/previous project HTML * Implemented Null Object pattern for context to support a Project having no default context * Removed tickler.rhtml, no longer in use * applying z-index values to project sortable list items (otherwise context autocomplete was appearing below next list item) * Swapped order of project and context in new action form (setting default context makes more sense this way) * Removed CSS width of for form elements, so form could be used in content area without being too narrow git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@480 a4c988fc-2ded-0310-b66e-134b36920a42
This commit is contained in:
parent
11ed78abe2
commit
38b2e336a8
21 changed files with 189 additions and 75 deletions
|
|
@ -111,6 +111,10 @@ class ApplicationController < ActionController::Base
|
|||
def markdown(text)
|
||||
RedCloth.new(text).to_html
|
||||
end
|
||||
|
||||
def build_default_project_context_name_map(projects)
|
||||
Hash[*projects.reject{ |p| p.default_context.nil? }.map{ |p| [p.name, p.default_context.name] }.flatten].to_json
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ class ContextsController < ApplicationController
|
|||
# Hides actions in hidden projects from context.
|
||||
@not_done_todos = @context.todos.find(:all, :conditions => ['todos.state = ?', 'active'], :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC", :include => :project)
|
||||
@count = @not_done_todos.size
|
||||
@default_project_context_name_map = build_default_project_context_name_map(@projects).to_json
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ class ProjectsController < ApplicationController
|
|||
helper :application, :todos, :notes
|
||||
before_filter :init, :except => [:create, :destroy, :order]
|
||||
before_filter :check_user_set_project, :only => [:update, :destroy, :show]
|
||||
before_filter :default_context_filter, :only => [:create,:update]
|
||||
skip_before_filter :login_required, :only => [:index]
|
||||
prepend_before_filter :login_or_feed_token_required, :only => [:index]
|
||||
session :off, :only => :index, :if => Proc.new { |req| ['rss','atom','txt'].include?(req.parameters[:format]) }
|
||||
|
|
@ -28,6 +29,7 @@ class ProjectsController < ApplicationController
|
|||
@count = @not_done.size
|
||||
@next_project = @user.projects.next_from(@project)
|
||||
@previous_project = @user.projects.previous_from(@project)
|
||||
@default_project_context_name_map = build_default_project_context_name_map(@projects).to_json
|
||||
end
|
||||
|
||||
# Example XML usage: curl -H 'Accept: application/xml' -H 'Content-Type: application/xml'
|
||||
|
|
@ -50,6 +52,7 @@ class ProjectsController < ApplicationController
|
|||
@saved = @project.save
|
||||
@project_not_done_counts = { @project.id => 0 }
|
||||
@active_projects_count = @user.projects.count(:conditions => "state = 'active'")
|
||||
@contexts = @user.contexts
|
||||
respond_to do |wants|
|
||||
wants.js
|
||||
wants.xml do
|
||||
|
|
@ -93,6 +96,8 @@ class ProjectsController < ApplicationController
|
|||
render
|
||||
elsif boolean_param('update_status')
|
||||
render :action => 'update_status'
|
||||
elsif boolean_param('update_default_context')
|
||||
render :action => 'update_default_context'
|
||||
else
|
||||
render :text => success_text || 'Success'
|
||||
end
|
||||
|
|
@ -181,6 +186,19 @@ class ProjectsController < ApplicationController
|
|||
@done = @user.todos.find_in_state(:all, :completed, :order => "completed_at DESC")
|
||||
init_data_for_sidebar
|
||||
end
|
||||
|
||||
def default_context_filter
|
||||
p = params['project']
|
||||
p = params['request']['project'] if p.nil? && params['request']
|
||||
p = {} if p.nil?
|
||||
default_context_name = p['default_context_name']
|
||||
p.delete('default_context_name')
|
||||
|
||||
unless default_context_name.blank?
|
||||
default_context = Context.find_or_create_by_name(default_context_name)
|
||||
p['default_context_id'] = default_context.id
|
||||
end
|
||||
end
|
||||
|
||||
def summary(project)
|
||||
project_description = ''
|
||||
|
|
|
|||
|
|
@ -224,6 +224,7 @@ class TodosController < ApplicationController
|
|||
@page_title = "TRACKS::Tickler"
|
||||
@tickles = @user.deferred_todos
|
||||
@count = @tickles.size
|
||||
@default_project_context_name_map = build_default_project_context_name_map(@projects).to_json
|
||||
end
|
||||
|
||||
# Check for any due tickler items, activate them
|
||||
|
|
@ -262,6 +263,7 @@ class TodosController < ApplicationController
|
|||
@done = @user.completed_todos.find(:all, :limit => max_completed, :include => [ :context, :project, :tags ]) unless max_completed == 0
|
||||
# Set count badge to number of items with this tag
|
||||
@not_done_todos.empty? ? @count = 0 : @count = @not_done_todos.size
|
||||
@default_project_context_name_map = build_default_project_context_name_map(@projects).to_json
|
||||
|
||||
end
|
||||
|
||||
|
|
@ -421,7 +423,9 @@ class TodosController < ApplicationController
|
|||
|
||||
# Set count badge to number of not-done, not hidden context items
|
||||
@count = @todos.reject { |x| !x.active? || x.context.hide? }.size
|
||||
|
||||
|
||||
@default_project_context_name_map = build_default_project_context_name_map(@projects).to_json
|
||||
|
||||
render
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ module ProjectsHelper
|
|||
project_name = truncate(@previous_project.name, 40, "...")
|
||||
html << link_to_project(@previous_project, "« #{project_name}")
|
||||
end
|
||||
html << '|' if @previous_project && @next_project
|
||||
html << ' | ' if @previous_project && @next_project
|
||||
unless @next_project.nil?
|
||||
project_name = truncate(@next_project.name, 40, "...")
|
||||
html << link_to_project(@next_project, "#{project_name} »")
|
||||
|
|
|
|||
|
|
@ -22,6 +22,10 @@ class Context < ActiveRecord::Base
|
|||
:description => "Lists all the contexts for #{user.display_name}"
|
||||
}
|
||||
end
|
||||
|
||||
def self.null_object
|
||||
NullContext.new
|
||||
end
|
||||
|
||||
def hidden?
|
||||
self.hide == true || self.hide == 1
|
||||
|
|
@ -43,3 +47,19 @@ class Context < ActiveRecord::Base
|
|||
end
|
||||
|
||||
end
|
||||
|
||||
class NullContext
|
||||
|
||||
def nil?
|
||||
true
|
||||
end
|
||||
|
||||
def id
|
||||
nil
|
||||
end
|
||||
|
||||
def name
|
||||
''
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
class Project < ActiveRecord::Base
|
||||
has_many :todos, :dependent => :delete_all, :include => :context
|
||||
has_many :notes, :dependent => :delete_all, :order => "created_at DESC"
|
||||
belongs_to :default_context, :dependent => :nullify, :class_name => "Context", :foreign_key => "default_context_id"
|
||||
belongs_to :user
|
||||
|
||||
validates_presence_of :name, :message => "project must have a name"
|
||||
|
|
@ -65,7 +66,13 @@ class Project < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
alias_method :original_default_context, :default_context
|
||||
|
||||
def default_context
|
||||
original_default_context.nil? ? Context.null_object : original_default_context
|
||||
end
|
||||
|
||||
# would prefer to call this method state=(), but that causes an endless loop
|
||||
# as a result of acts_as_state_machine calling state=() to update the attribute
|
||||
def transition_to(candidate_state)
|
||||
|
|
@ -96,5 +103,5 @@ class NullProject
|
|||
def id
|
||||
nil
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<div class="page_name_auto_complete" id="default_context_list" style="display:none;z-index:9999"></div>
|
||||
<script type="text/javascript">
|
||||
defaultContextAutoCompleter = new Autocompleter.Local('project[default_context_name]', 'default_context_list', <%= context_names_for_autocomplete %>, {choices:100,autoSelect:true});
|
||||
Event.observe($('project[default_context_name]'), "focus", defaultContextAutoCompleter.activate.bind(defaultContextAutoCompleter));
|
||||
Event.observe($('project[default_context_name]'), "click", defaultContextAutoCompleter.activate.bind(defaultContextAutoCompleter));
|
||||
</script>
|
||||
|
|
@ -17,3 +17,10 @@
|
|||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="150"><label for="project[default_context_name]">Default Context</label></td>
|
||||
<td width="300">
|
||||
<%= text_field_tag("project[default_context_name]", @project.default_context.name, {:tabindex=>1,:size=> 25}) %>
|
||||
<%= render :partial => 'default_context_autocomplete' %>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
<% project = project_listing %>
|
||||
<div id="<%= dom_id(project, "container") %>" class="list">
|
||||
<div id="<%= dom_id(project) %>" class="project sortable_row" style="display:'';">
|
||||
<% project = project_listing
|
||||
@project_listing_zindex = @project_listing_zindex.nil? ? 200 : @project_listing_zindex - 1
|
||||
-%>
|
||||
<div id="<%= dom_id(project, "container") %>" class="list" style="z-index:<%= @project_listing_zindex %>">
|
||||
<div id="<%= dom_id(project) %>" class="project sortable_row" style="display:''">
|
||||
<div class="position">
|
||||
<span class="handle">DRAG</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -21,14 +21,19 @@
|
|||
<div id="status"><%= error_messages_for('project') %></div>
|
||||
|
||||
<label for="project_name">Name:</label><br />
|
||||
<%= text_field 'project', 'name' %><br />
|
||||
<%= text_field 'project', 'name', "tabindex" => 1 %><br />
|
||||
|
||||
<label for="project_description">Description (optional):</label><br />
|
||||
<%= text_area 'project', 'description', "cols" => 30, "rows" => 4 %><br />
|
||||
|
||||
<%= check_box_tag 'go_to_project' %><label for="go_to_project">Go to the project page</label><br />
|
||||
<%= text_area 'project', 'description', "cols" => 30, "rows" => 4, "tabindex" => 2 %><br />
|
||||
|
||||
<input type="submit" value="Add" />
|
||||
<label for="default_context_name">Default Context (optional):</label><br />
|
||||
<%= text_field_tag("project[default_context_name]", @project.default_context.name, :tabindex => 3) %>
|
||||
<%= render :partial => 'default_context_autocomplete' %>
|
||||
<br />
|
||||
|
||||
<input type="submit" value="Add Project" tabindex="4" /><br />
|
||||
|
||||
<input id="go_to_project" type="checkbox" tabindex="5" name="go_to_project"/><label for="go_to_project"> Take me to the new project page</label><br />
|
||||
|
||||
<% end -%>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -18,21 +18,21 @@
|
|||
<%= render :partial => "notes/notes_summary", :collection => @project.notes %>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<div id="new-note" style="display:none;">
|
||||
<% form_remote_tag :url => notes_path,
|
||||
:method => :post,
|
||||
|
||||
<div id="new-note" style="display:none;">
|
||||
<% form_remote_tag :url => notes_path,
|
||||
:method => :post,
|
||||
:update => "notes",
|
||||
:position => "bottom",
|
||||
:complete => "new Effect.Highlight('notes');$('empty-n').hide();",
|
||||
:html => {:id=>'form-new-note', :class => 'inline-form'} do %>
|
||||
<%= hidden_field( "new_note", "project_id", "value" => "#{@project.id}" ) %>
|
||||
<%= text_area( "new_note", "body", "cols" => 50, "rows" => 3, "tabindex" => 1 ) %>
|
||||
<br /><br />
|
||||
<input type="submit" value="Add note" tabindex="2" />
|
||||
<% end -%>
|
||||
</div>
|
||||
<%= hidden_field( "new_note", "project_id", "value" => "#{@project.id}" ) %>
|
||||
<%= text_area( "new_note", "body", "cols" => 50, "rows" => 3, "tabindex" => 1 ) %>
|
||||
<br /><br />
|
||||
<input type="submit" value="Add note" tabindex="2" />
|
||||
<% end -%>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div id="project_status">
|
||||
|
|
@ -49,6 +49,24 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div id="default_context">
|
||||
<h2>Default Context</h2>
|
||||
<div>
|
||||
<% form_remote_tag( :url => project_path(@project), :method => :put,
|
||||
:html=> { :id => 'set-default-context-action',
|
||||
:name => 'default_context',
|
||||
:class => 'inline-form' }) do -%>
|
||||
<%= hidden_field_tag("update_default_context", true) %>
|
||||
<%= text_field_tag("project[default_context_name]",
|
||||
@project.default_context.name,
|
||||
{ :tabindex => 9,:size => 25 }) %>
|
||||
<%= submit_tag "Set Default Context for this Project", { :tabindex => 10 } %>
|
||||
<%= render :partial => 'default_context_autocomplete' %>
|
||||
<% end -%>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- [end:display_box] -->
|
||||
|
||||
|
|
|
|||
10
tracks/app/views/projects/update_default_context.rjs
Normal file
10
tracks/app/views/projects/update_default_context.rjs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
if @project.default_context.nil?
|
||||
page.notify :notice, "Removed default context", 5.0
|
||||
else
|
||||
if source_view_is :project
|
||||
page['todo_context_name'].value = @project.default_context.name
|
||||
end
|
||||
page.notify :notice, "Set project's default context to #{@project.default_context.name}", 5.0
|
||||
end
|
||||
page.hide "busy"
|
||||
|
||||
|
|
@ -8,3 +8,4 @@ page.select('#project_status .completed span').each do |element|
|
|||
element.className = @project.current_state == :completed ? 'active_state' : 'inactive_state'
|
||||
end
|
||||
page.notify :notice, "Set project status to #{@project.current_state}", 5.0
|
||||
page.hide 'busy'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<%
|
||||
@todo = nil
|
||||
@initial_context_name = @context.name unless @context.nil?
|
||||
@initial_context_name ||= @project.default_context.name unless @project.nil? || @project.default_context.nil?
|
||||
@initial_context_name ||= @contexts[0].name unless @contexts[0].nil?
|
||||
@initial_project_name = @project.name unless @project.nil?
|
||||
%>
|
||||
|
|
@ -24,24 +25,34 @@
|
|||
<label for="todo_notes">Notes</label>
|
||||
<%= text_area( "todo", "notes", "cols" => 25, "rows" => 6, "tabindex" => 2) %>
|
||||
|
||||
<label for="todo_context_name">Context</label>
|
||||
<input id="todo_context_name" name="context_name" autocomplete="off" tabindex="3" size="25" type="text" value="<%= @initial_context_name %>" />
|
||||
<div class="page_name_auto_complete" id="context_list" style="display:none"></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
contextAutoCompleter = new Autocompleter.Local('todo_context_name', 'context_list', <%= context_names_for_autocomplete %>, {choices:100,autoSelect:true});
|
||||
Event.observe($('todo_context_name'), "focus", contextAutoCompleter.activate.bind(contextAutoCompleter));
|
||||
Event.observe($('todo_context_name'), "click", contextAutoCompleter.activate.bind(contextAutoCompleter));
|
||||
</script>
|
||||
|
||||
<label for="todo_project_name">Project</label>
|
||||
<input id="todo_project_name" name="project_name" autocomplete="off" tabindex="4" size="25" type="text" value="<%= @initial_project_name %>" />
|
||||
<input id="todo_project_name" name="project_name" autocomplete="off" tabindex="3" size="25" type="text" value="<%= @initial_project_name %>" />
|
||||
<div class="page_name_auto_complete" id="project_list" style="display:none"></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
projectAutoCompleter = new Autocompleter.Local('todo_project_name', 'project_list', <%= project_names_for_autocomplete %>, {choices:100,autoSelect:true});
|
||||
function selectDefaultContext() {
|
||||
todoContextNameElement = $('todo_context_name');
|
||||
defaultContextName = todoContextNameElement.projectDefaultContextsMap[this.value];
|
||||
if (defaultContextName && !todoContextNameElement.editedByTracksUser) {
|
||||
todoContextNameElement.value = defaultContextName;
|
||||
}
|
||||
}
|
||||
Event.observe($('todo_project_name'), "focus", projectAutoCompleter.activate.bind(projectAutoCompleter));
|
||||
Event.observe($('todo_project_name'), "click", projectAutoCompleter.activate.bind(projectAutoCompleter));
|
||||
Event.observe($('todo_project_name'), "blur", selectDefaultContext.bind($('todo_project_name')));
|
||||
</script>
|
||||
|
||||
<label for="todo_context_name">Context</label>
|
||||
<input id="todo_context_name" name="context_name" autocomplete="off" tabindex="4" size="25" type="text" value="<%= @initial_context_name %>" />
|
||||
<div class="page_name_auto_complete" id="context_list" style="display:none"></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
contextAutoCompleter = new Autocompleter.Local('todo_context_name', 'context_list', <%= context_names_for_autocomplete %>, {choices:100,autoSelect:true});
|
||||
$('todo_context_name').projectDefaultContextsMap = <%= @default_project_context_name_map %>;
|
||||
Event.observe($('todo_context_name'), "focus", function(){ $('todo_context_name').editedByTracksUser = true; });
|
||||
Event.observe($('todo_context_name'), "focus", contextAutoCompleter.activate.bind(contextAutoCompleter));
|
||||
Event.observe($('todo_context_name'), "click", contextAutoCompleter.activate.bind(contextAutoCompleter));
|
||||
</script>
|
||||
|
||||
<label for="tag_list">Tags (separate with commas)</label>
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
<div id="display_box">
|
||||
|
||||
<div id="tickler" class="container project">
|
||||
<h2>Deferred actions</h2>
|
||||
|
||||
<div id="tickler-items" class="items toggle_target">
|
||||
<div id="tickler-empty-nd" style="display:<%= @tickles.empty? ? 'block' : 'none'%>;">
|
||||
<div class="message"><p>Currently there are no deferred actions</p></div>
|
||||
</div>
|
||||
|
||||
<%= render :partial => "todos/todo", :collection => @tickles, :locals => { :parent_container_type => 'tickler' } %>
|
||||
|
||||
</div><!-- [end:items] -->
|
||||
</div><!-- [end:tickler] -->
|
||||
|
||||
</div><!-- End of display_box -->
|
||||
|
||||
<div id="input_box">
|
||||
<%= render :partial => "shared/add_new_item_form" %>
|
||||
<%= render "sidebar/sidebar" %>
|
||||
</div><!-- End of input box -->
|
||||
9
tracks/db/migrate/031_add_default_context_to_project.rb
Normal file
9
tracks/db/migrate/031_add_default_context_to_project.rb
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
class AddDefaultContextToProject < ActiveRecord::Migration
|
||||
def self.up
|
||||
add_column :projects, :default_context_id, :integer
|
||||
end
|
||||
|
||||
def self.down
|
||||
remove_column :projects, :default_context_id, :integer
|
||||
end
|
||||
end
|
||||
|
|
@ -2,17 +2,18 @@
|
|||
# migrations feature of ActiveRecord to incrementally modify your database, and
|
||||
# then regenerate this schema definition.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 30) do
|
||||
ActiveRecord::Schema.define(:version => 31) 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 "name", :string, :default => "", :null => false
|
||||
t.column "hide", :boolean, :default => false
|
||||
t.column "user_id", :integer, :default => 1
|
||||
t.column "position", :integer, :default => 0, :null => false
|
||||
t.column "user_id", :integer, :default => 0, :null => false
|
||||
t.column "created_at", :datetime
|
||||
t.column "updated_at", :datetime
|
||||
end
|
||||
|
||||
add_index "contexts", ["user_id"], :name => "index_contexts_on_user_id"
|
||||
add_index "contexts", ["user_id", "name"], :name => "index_contexts_on_user_id_and_name"
|
||||
|
||||
create_table "notes", :force => true do |t|
|
||||
|
|
@ -63,15 +64,17 @@ ActiveRecord::Schema.define(:version => 30) do
|
|||
add_index "preferences", ["user_id"], :name => "index_preferences_on_user_id"
|
||||
|
||||
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
|
||||
t.column "created_at", :datetime
|
||||
t.column "updated_at", :datetime
|
||||
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
|
||||
t.column "created_at", :datetime
|
||||
t.column "updated_at", :datetime
|
||||
t.column "default_context_id", :integer
|
||||
end
|
||||
|
||||
add_index "projects", ["user_id"], :name => "index_projects_on_user_id"
|
||||
add_index "projects", ["user_id", "name"], :name => "index_projects_on_user_id_and_name"
|
||||
|
||||
create_table "sessions", :force => true do |t|
|
||||
|
|
@ -100,16 +103,16 @@ ActiveRecord::Schema.define(:version => 30) do
|
|||
add_index "tags", ["name"], :name => "index_tags_on_name"
|
||||
|
||||
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 "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 "user_id", :integer, :default => 1
|
||||
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
|
||||
t.column "state", :string, :limit => 20, :default => "immediate", :null => false
|
||||
end
|
||||
|
||||
add_index "todos", ["user_id", "state"], :name => "index_todos_on_user_id_and_state"
|
||||
|
|
@ -119,10 +122,10 @@ ActiveRecord::Schema.define(:version => 30) do
|
|||
add_index "todos", ["user_id", "context_id"], :name => "index_todos_on_user_id_and_context_id"
|
||||
|
||||
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 "login", :string, :limit => 80
|
||||
t.column "password", :string, :limit => 40
|
||||
t.column "word", :string
|
||||
t.column "is_admin", :boolean, :default => false, :null => false
|
||||
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
|
||||
|
|
|
|||
|
|
@ -313,6 +313,10 @@ div#project_status > div {
|
|||
#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;}
|
||||
|
||||
|
|
@ -557,7 +561,6 @@ form {
|
|||
border: 1px solid #CCC;
|
||||
padding: 10px;
|
||||
margin: 0px;
|
||||
width: 313px;
|
||||
}
|
||||
.inline-form {
|
||||
border: none;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
setup :fixtures => :all
|
||||
include_partial 'login/login', :username => 'admin', :password => 'abracadabra'
|
||||
open "/todos/tag/foo"
|
||||
wait_for_element_present "xpath=//div[@id='t'] //h2"
|
||||
assert_not_visible "t_empty-nd"
|
||||
wait_for_element_present "xpath=//div[@id='c1'] //h2"
|
||||
wait_for_text 'badge_count', '2'
|
||||
|
|
@ -192,5 +192,12 @@ class ProjectTest < Test::Unit::TestCase
|
|||
@moremoney.todos[0].complete!
|
||||
assert_equal 2, @moremoney.not_done_todo_count
|
||||
end
|
||||
|
||||
def test_default_context_name
|
||||
p = Project.new
|
||||
assert_equal '', p.default_context.name
|
||||
p.default_context = contexts(:agenda)
|
||||
assert_equal 'agenda', p.default_context.name
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue