diff --git a/tracks/app/controllers/note_controller.rb b/tracks/app/controllers/note_controller.rb new file mode 100644 index 00000000..0656ebd9 --- /dev/null +++ b/tracks/app/controllers/note_controller.rb @@ -0,0 +1,50 @@ +class NoteController < ApplicationController + + layout "standard" + + def index + @all_notes = Note.list_all + @page_title = "TRACKS::All notes" + end + + def show + @note = Note.find(@params[:id]) + @page_title = "TRACKS::Note " + @note.id.to_s + end + + # Add a new note to this project + # + def add_note + + note = Note.new + note.attributes = @params["new_note"] + + if note.save + render_partial 'notes_summary', note + else + render_text "" + end + end + + def destroy_note + note = Note.find_by_id(@params[:id]) + if note.destroy + render_text "" + else + flash["warning"] = "Couldn't delete note \"#{note.id.to_s}\"" + render_text "" + end + end + + def update_note + note = Note.find_by_id(@params[:id]) + note.attributes = @params["note"] + if note.save + render_partial 'notes', note + else + flash["warning"] = "Couldn't update note \"#{note.id.to_s}\"" + render_text "" + end + end + +end diff --git a/tracks/app/controllers/project_controller.rb b/tracks/app/controllers/project_controller.rb index 6eb168c2..21eccdd5 100644 --- a/tracks/app/controllers/project_controller.rb +++ b/tracks/app/controllers/project_controller.rb @@ -141,6 +141,7 @@ class ProjectController < ApplicationController render_partial 'show_items', item end + # Methods for changing the sort order of the projects in the list # def move_up diff --git a/tracks/app/helpers/note_helper.rb b/tracks/app/helpers/note_helper.rb new file mode 100644 index 00000000..d27337d4 --- /dev/null +++ b/tracks/app/helpers/note_helper.rb @@ -0,0 +1,2 @@ +module NoteHelper +end diff --git a/tracks/app/models/note.rb b/tracks/app/models/note.rb new file mode 100644 index 00000000..115ae51b --- /dev/null +++ b/tracks/app/models/note.rb @@ -0,0 +1,13 @@ +class Note < ActiveRecord::Base + + belongs_to :project + + def self.list_all + find(:all, :order => "created_at DESC") + end + + def self.list_of(project_id) + find(:all, :conditions => [ "project_id = ?" , project_id ]) + end + +end diff --git a/tracks/app/models/project.rb b/tracks/app/models/project.rb index 5b68d4ff..a3b4d55f 100644 --- a/tracks/app/models/project.rb +++ b/tracks/app/models/project.rb @@ -1,6 +1,7 @@ class Project < ActiveRecord::Base has_many :todo, :dependent => true + has_many :note acts_as_list # Project name must not be empty diff --git a/tracks/app/views/layouts/standard.rhtml b/tracks/app/views/layouts/standard.rhtml index 0175a569..0edb603f 100644 --- a/tracks/app/views/layouts/standard.rhtml +++ b/tracks/app/views/layouts/standard.rhtml @@ -28,6 +28,7 @@
  • <%= link_to( "Contexts", {:controller => "context", :action => "list"}, {:accesskey=>"c", :title=>"Contexts AccessKey: Alt+C"} ) %>
  • <%= link_to( "Projects", {:controller => "project", :action => "list"}, {:accesskey=>"p", :title=>"Projects AccessKey: Alt+P"} ) %>
  • <%= link_to( "Completed", {:controller => "todo", :action => "completed"}, {:accesskey=>"d", :title=>"Completed AccessKey: Alt+D"} ) %>
  • +
  • <%= link_to( "Notes", {:controller => "note", :action => "index"}, :title => "Show all notes" ) %>
  • Show
  • Hide
  • <%= link_to("RSS", {:controller => "feed", :action => "na_feed", :name => "#{@session['user']['login']}", :token => "#{@session['user']['word']}"}, :title => "Subscribe to an RSS feed of your next actions" ) %>
  • diff --git a/tracks/app/views/note/_note_edit_form.rhtml b/tracks/app/views/note/_note_edit_form.rhtml new file mode 100644 index 00000000..49ae4deb --- /dev/null +++ b/tracks/app/views/note/_note_edit_form.rhtml @@ -0,0 +1,6 @@ +<% @note = note_edit_form %> +<%= hidden_field( "note", "project_id" ) %> +<%= text_area( "note", "body", "cols" => 70, "rows" => 15, "tabindex" => 1 ) %> +

    + +<% @note = nil %> \ No newline at end of file diff --git a/tracks/app/views/note/_notes.rhtml b/tracks/app/views/note/_notes.rhtml new file mode 100644 index 00000000..4fb0b5a0 --- /dev/null +++ b/tracks/app/views/note/_notes.rhtml @@ -0,0 +1,33 @@ +<% note = notes -%> +
    +

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

    + +
    + <%= textilize(note.body) %> + + +
    + + + +
    +<% note = nil -%> \ No newline at end of file diff --git a/tracks/app/views/note/_notes_summary.rhtml b/tracks/app/views/note/_notes_summary.rhtml new file mode 100644 index 00000000..50ad67a2 --- /dev/null +++ b/tracks/app/views/note/_notes_summary.rhtml @@ -0,0 +1,6 @@ +<% note = notes_summary -%> +
    +<%= link_to(image_tag("blank"), {:controller => "note", :action => "show", :id => note.id}, :title => "Show note", :class => "show_notes" ) %>  +<%= textilize(truncate(note.body, 50, "...")) %> +
    +<% note = nil -%> \ No newline at end of file diff --git a/tracks/app/views/note/index.rhtml b/tracks/app/views/note/index.rhtml new file mode 100644 index 00000000..9638074c --- /dev/null +++ b/tracks/app/views/note/index.rhtml @@ -0,0 +1,7 @@ +
    + <% for notes in @all_notes -%> +
    + <%= render_partial "notes", notes %> +
    + <% end -%> +
    \ No newline at end of file diff --git a/tracks/app/views/note/show.rhtml b/tracks/app/views/note/show.rhtml new file mode 100644 index 00000000..5a350a1a --- /dev/null +++ b/tracks/app/views/note/show.rhtml @@ -0,0 +1,5 @@ +
    +
    + <%= render_partial "notes", @note %> +
    +
    \ No newline at end of file diff --git a/tracks/app/views/project/show.rhtml b/tracks/app/views/project/show.rhtml index cf7b22b0..2afad4a3 100644 --- a/tracks/app/views/project/show.rhtml +++ b/tracks/app/views/project/show.rhtml @@ -33,6 +33,35 @@ + +<% @notes = Note.list_of(@project.id) -%> +
    + +
    +

    Notes

    + <% for note in @notes -%> + <%= render_partial "note/notes_summary", note %> + <% end -%> +
    +
    + + +<%= link_to_function( "Add a note", + "Element.toggle('new-note'); Form.focusFirstElement('form-new-note');") %> + + +
    diff --git a/tracks/config/routes.rb b/tracks/config/routes.rb index cbee3442..8a52cb7d 100644 --- a/tracks/config/routes.rb +++ b/tracks/config/routes.rb @@ -37,6 +37,12 @@ ActionController::Routing::Routes.draw do |map| map.connect 'project/:name', :controller => 'project', :action => 'show' map.connect 'project/:id', :controller => 'project', :action => 'show' + # Notes Routes + map.connect 'note/add_note', :controller => 'note', :action => 'add_note' + map.connect 'note/update_note/:id', :controller => 'note', :action => 'update_note', :id => 'id' + map.connect 'note/:id', :controller => 'note', :action => 'show', :id => 'id' + map.connect 'notes', :controller => 'note', :action => 'index' + # Feed Routes map.connect 'feed/:action/:name/:user', :controller => 'feed' diff --git a/tracks/db/tracks_1.0.3_mysql.sql b/tracks/db/tracks_1.0.3_mysql.sql index b2fa2f86..02696ea6 100644 --- a/tracks/db/tracks_1.0.3_mysql.sql +++ b/tracks/db/tracks_1.0.3_mysql.sql @@ -64,4 +64,17 @@ CREATE TABLE `users` ( ) TYPE=MyISAM; +-- Dump of table notes +-- ------------------------------------------------------------ + +CREATE TABLE `notes` ( + `id` int(11) NOT NULL auto_increment, + `project_id` int(11) NOT NULL default '0', + `body` text, + `created_at` datetime NOT NULL default '0000-00-00 00:00:00', + `updated_at` datetime default '0000-00-00 00:00:00', + PRIMARY KEY (`id`) +) TYPE=MyISAM; + + diff --git a/tracks/db/tracks_1.0.3_postgres.sql b/tracks/db/tracks_1.0.3_postgres.sql index 8b0560d5..c610810e 100644 --- a/tracks/db/tracks_1.0.3_postgres.sql +++ b/tracks/db/tracks_1.0.3_postgres.sql @@ -53,4 +53,16 @@ create table users ( ); -- Set the sequence to the proper value -select setval('users_id_seq', (select max(id) from users)); \ No newline at end of file +select setval('users_id_seq', (select max(id) from users)); + +create table notes ( + id serial not null, + project_id int not null default 0, + body text, + created_at timestamp default null, + updated_at timestamp default null, + primary key (id) +); + +-- Set the sequence to the proper value +select setval('notes_id_seq', (select max(id) from notes)); \ No newline at end of file diff --git a/tracks/db/tracks_1.0.3_sqlite.sql b/tracks/db/tracks_1.0.3_sqlite.sql index b613ced1..c75d23d9 100644 --- a/tracks/db/tracks_1.0.3_sqlite.sql +++ b/tracks/db/tracks_1.0.3_sqlite.sql @@ -52,3 +52,15 @@ CREATE TABLE 'users' ( 'word' varchar(255) default NULL, 'is_admin' tinyint(4) NOT NULL default '0' ) ; + +-- Dump of table notes +-- ------------------------------------------------------------ + +CREATE TABLE 'notes' ( + 'id' INTEGER PRIMARY KEY, + 'project_id' int(11) NOT NULL default '0', + 'body' text, + 'created_at' datetime NOT NULL default '0000-00-00 00:00:00', + 'updated_at' datetime default '0000-00-00 00:00:00' +) ; + diff --git a/tracks/doc/CHANGELOG b/tracks/doc/CHANGELOG index f09af8e2..7c38b49e 100644 --- a/tracks/doc/CHANGELOG +++ b/tracks/doc/CHANGELOG @@ -13,6 +13,12 @@ Trac (for bug reports and feature requests): http://dev.rousette.org.uk/report/6 Wiki (deprecated - please use Trac): http://www.rousette.org.uk/projects/wiki/ +== Version 1.04 + +1. Tidied up the interface a bit, fixing mistakes in the wording. +2. The number of actions reported is now correctly pluralized depending on the number of actions (e.g. 1 action, 2 actions). +3. Added a Note model and notes database table. Notes have their own interface (/notes lists them all, and /note/1 shows note id 1), but they are displayed on the /project/show/[name] page. For now, notes belong to a particular project, and are added from the /project/show/[name] pages. You can delete and edit notes either from the /notes page or from the /note/[id] page. Notes use Textile/Markdown formatting. + == Version 1.03 13. All the adding, updating, deleting and marking actions done is performed using Ajax, so happens without needing to refresh the page. diff --git a/tracks/public/stylesheets/standard.css b/tracks/public/stylesheets/standard.css index 2fefbf20..64cecd38 100644 --- a/tracks/public/stylesheets/standard.css +++ b/tracks/public/stylesheets/standard.css @@ -156,7 +156,6 @@ a.refresh, a.refresh:link, a.refresh:active {color: #57A620;} margin-top: 20px; width: 313px; padding: 0px 15px 0px 15px; - /* border: 1px solid #999; */ } #input_box h2 { @@ -227,6 +226,35 @@ div.big-box, div.big-box a, div.big-box a:hover { list-style-type: decimal; margin-left: 5px; } + +/* The notes for the project */ + +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; + } + +a.footer_link {color: #cc3334; font-style: normal;} +a.footer_link:hover {color: #fff; background-color: #cc3334 !important;} /* The alert box notifications */ .confirmation { diff --git a/tracks/test/fixtures/notes.yml b/tracks/test/fixtures/notes.yml new file mode 100644 index 00000000..cce14437 --- /dev/null +++ b/tracks/test/fixtures/notes.yml @@ -0,0 +1,5 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html +first_notes: + id: 1 +another_notes: + id: 2 diff --git a/tracks/test/functional/note_controller_test.rb b/tracks/test/functional/note_controller_test.rb new file mode 100644 index 00000000..7a398cdf --- /dev/null +++ b/tracks/test/functional/note_controller_test.rb @@ -0,0 +1,18 @@ +require File.dirname(__FILE__) + '/../test_helper' +require 'note_controller' + +# Re-raise errors caught by the controller. +class NoteController; def rescue_action(e) raise e end; end + +class NoteControllerTest < Test::Unit::TestCase + def setup + @controller = NoteController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + end + + # Replace this with your real tests. + def test_truth + assert true + end +end diff --git a/tracks/test/unit/notes_test.rb b/tracks/test/unit/notes_test.rb new file mode 100644 index 00000000..cc9bc619 --- /dev/null +++ b/tracks/test/unit/notes_test.rb @@ -0,0 +1,14 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class NotesTest < Test::Unit::TestCase + fixtures :notes + + def setup + @notes = Notes.find(1) + end + + # Replace this with your real tests. + def test_truth + assert_kind_of Notes, @notes + end +end