From 3b5857267893c80cfd69d98c6b8de6a00eb69e93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Tufr=C3=B3?= Date: Tue, 3 Aug 2010 14:59:38 -0300 Subject: [PATCH] Added releases feature --- app/controllers/stories_controller.rb | 1 + app/models/story.rb | 2 +- app/views/backlog/_menu.html.haml | 2 ++ app/views/stories/_form.html.haml | 23 +++++++++++++----- app/views/stories/_story.html.haml | 23 +++++++++--------- app/views/stories/edit.html.haml | 2 +- app/views/stories/new.html.haml | 2 +- config/routes.rb | 1 + .../20100803173622_add_release_to_story.rb | 9 +++++++ public/images/CD.png | Bin 0 -> 6871 bytes public/images/add_release.png | Bin 0 -> 8061 bytes public/javascripts/helpers/stories.js | 16 +++++++++--- public/stylesheets/sass/backlog.sass | 2 ++ public/stylesheets/sass/menu.sass | 8 +++++- test/unit/story_test.rb | 3 ++- 15 files changed, 68 insertions(+), 26 deletions(-) create mode 100644 db/migrate/20100803173622_add_release_to_story.rb create mode 100755 public/images/CD.png create mode 100644 public/images/add_release.png diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index 3d27afb..66bc8ba 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -14,6 +14,7 @@ def index # GET /projects/:project_id/stories/new def new @story = (params[:team_id].blank?) ? @project.stories.build : Story.new + @story.release = true if(!params[:release].blank?) @projects = @team.projects if !params[:team_id].blank? @default_realid = @project ? @project.next_realid : @team.projects.first.next_realid @default_priority = @project ? @project.next_priority : @team.next_priority diff --git a/app/models/story.rb b/app/models/story.rb index c1e750b..1b4773c 100644 --- a/app/models/story.rb +++ b/app/models/story.rb @@ -19,7 +19,7 @@ class Story < ActiveRecord::Base # Attributes Accessible # ################################################################################################################ - attr_accessible :name, :priority, :size, :description, :realid, :project + attr_accessible :name, :priority, :size, :description, :realid, :project, :release ################################################################################################################ # diff --git a/app/views/backlog/_menu.html.haml b/app/views/backlog/_menu.html.haml index 5062498..0723f51 100644 --- a/app/views/backlog/_menu.html.haml +++ b/app/views/backlog/_menu.html.haml @@ -9,6 +9,8 @@ .item.new_story{ 'data-project-id' => @project.to_param, 'data-team-id' => @team.to_param } - link_to @view == :project ? project_backlog_export_path(@project.to_param) : team_backlog_export_path(@team.to_param) do .item.export_backlog + + .item.new_release{ 'data-project-id' => @project.to_param, 'data-team-id' => @team.to_param } - link_to logout_path do .item.logout diff --git a/app/views/stories/_form.html.haml b/app/views/stories/_form.html.haml index 5c4d1bd..91dce71 100644 --- a/app/views/stories/_form.html.haml +++ b/app/views/stories/_form.html.haml @@ -8,17 +8,28 @@ = form.label :name = form.text_field :name -.field - = form.label :realid, "Story ID" - = form.text_field :realid, :value => @story.realid ? @story.realid : @default_realid +- if @story.release? + = form.hidden_field :realid, :value => @story.realid ? @story.realid : @default_realid +- else + .field + = form.label :realid, "Story ID" + = form.text_field :realid, :value => @story.realid ? @story.realid : @default_realid .field = form.label :priority = form.text_field :priority, :value => @story.priority ? @story.priority : @default_priority -.field - = form.label :size - = form.text_field :size +- if @story.release? + = form.hidden_field :size, :value => 9000 +- else + .field + = form.label :size + = form.text_field :size + +- if @story.release? + = form.hidden_field :release, :value => true +- else + = form.hidden_field :release, :value => false .field = form.label :description diff --git a/app/views/stories/_story.html.haml b/app/views/stories/_story.html.haml index b559c75..4f4b71c 100644 --- a/app/views/stories/_story.html.haml +++ b/app/views/stories/_story.html.haml @@ -1,7 +1,7 @@ -%tr.story{:id => "story-#{story.id}", :class => "#{story.status}", 'data-story-id' => story.id, 'data-project-id' => story.project_id} +%tr.story{:id => "story-#{story.id}", :class => "#{story.status} #{ 'release' if story.release? }", 'data-story-id' => story.id, 'data-project-id' => story.project_id} %td.name-cell %strong - = story.realid + = story.release? ? 'RELEASE' : story.realid = story.name - if @view == :team == - #{link_to("#{story.project.name}", project_backlog_index_path(story.project.id))} - @@ -28,7 +28,7 @@ == #{link_to_remote "Delete", :url => project_story_url(story.project,story), :confirm => 'Are you sure?', :method => :delete, :complete => "location.reload(true);"} ] - else == [ #{link_to_remote('Re-open', :url => project_story_start_path(story.project, story), :success => 'location = location')} / Date Finished: #{story.updated_at.strftime("%d %b %Y")}] - %td.priority-cell + %td.priority-cell{ :colspan => story.release? ? 2 : 1 } %span.in_place_edit{ :id => "priority-#{story.id}" } - if !story.finished? %p{ :id => "edit_priority_#{story.id}"}= story.priority @@ -36,13 +36,14 @@ new Ajax.InPlaceEditor('edit_priority_#{story.id}', '/projects/#{story.project.to_param}/stories/#{story.to_param}/update_priority', {cancelControl: 'button', onComplete: function(){ location = location }}); - else %p - - %td.size-cell - %span.in_place_edit{ :id => "size-#{story.id}" } - - if !story.finished? - %p{ :id => "edit_size_#{story.id}"}= story.size ? story.size : "Edit" - :javascript - new Ajax.InPlaceEditor('edit_size_#{story.id}', '/projects/#{story.project.to_param}/stories/#{story.to_param}/update_size', { cancelControl: 'button' }); - - else - %p= story.id + - if !story.release? + %td.size-cell + %span.in_place_edit{ :id => "size-#{story.id}" } + - if !story.finished? + %p{ :id => "edit_size_#{story.id}"}= story.size ? story.size : "Edit" + :javascript + new Ajax.InPlaceEditor('edit_size_#{story.id}', '/projects/#{story.project.to_param}/stories/#{story.to_param}/update_size', { cancelControl: 'button' }); + - else + %p= story.id %td.description-cell = story.description diff --git a/app/views/stories/edit.html.haml b/app/views/stories/edit.html.haml index 833eb0e..3f68d1f 100644 --- a/app/views/stories/edit.html.haml +++ b/app/views/stories/edit.html.haml @@ -1,6 +1,6 @@ #form #form-logo= image_tag "logo-projects.png" - %h1.organization Edit Story + %h1.organization== Edit #{ @story.release? ? 'Release' : 'Story' } - remote_form_for @story, :url => project_story_path(@project, @story, :format => :json), :success => 'Stories.afterUpdate(request.responseText);', :failure => 'ModalDialog.displayFormErrors(request.responseJSON);' do |f| = render :partial => 'form', :object => f = f.submit \ No newline at end of file diff --git a/app/views/stories/new.html.haml b/app/views/stories/new.html.haml index 05f967e..4dc288d 100644 --- a/app/views/stories/new.html.haml +++ b/app/views/stories/new.html.haml @@ -1,6 +1,6 @@ #form #form-logo= image_tag "logo-projects.png" - %h1.organization Create Story + %h1.organization== Add #{ @story.release? ? 'Release' : 'Story' } - remote_form_for @story, :url => (params[:team_id].blank?) ? project_stories_path(@project, :format => :json) : team_stories_path(@team, :format => :json), :success => 'Stories.afterCreate(request.responseText);', :failure => 'ModalDialog.displayFormErrors(request.responseJSON);' do |f| = render :partial => 'form', :object => f = f.submit \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 0d64535..b431dab 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -31,6 +31,7 @@ p.resources :taskboard, :only => [:index] p.resources :backlog, :only => [:index] p.backlog_export 'backlog/export', :controller => :backlog, :action => :export + p.new_release 'releases/new', :controller => :stories, :action => :new, :release => true p.resources :stories do |s| s.resources :tasks, :has_many => [ :statustags, :nametags ] s.task_start 'tasks/:id/start', :controller => :tasks, :action => :start, :conditions => { :method => :post } diff --git a/db/migrate/20100803173622_add_release_to_story.rb b/db/migrate/20100803173622_add_release_to_story.rb new file mode 100644 index 0000000..60d5461 --- /dev/null +++ b/db/migrate/20100803173622_add_release_to_story.rb @@ -0,0 +1,9 @@ +class AddReleaseToStory < ActiveRecord::Migration + def self.up + add_column :stories, :release, :boolean + end + + def self.down + remove_column :stories, :release + end +end diff --git a/public/images/CD.png b/public/images/CD.png new file mode 100755 index 0000000000000000000000000000000000000000..36a8825bdf6f9d636be7d3228e40b7fd88b22d50 GIT binary patch literal 6871 zcmV;|8Ytz7P)v8W-9iPDxJXc8iXEFi5?0a0jE1r@1j zAW}nth(aU+21El1RY*!pVl1dp62LqfVh39gAee_Ac-QOo?##~2eVu;)Vl~ckbLd|Nnpg`@hzEZ{FvBGqFC7HH;NvHL+S)BUqcTcE6vS3E$)UAAof>)}LS< zj5UBY)QZ#DdG7Js%zlqQW35g4Ytfs^2wE>=J&E-M)|>Cu2JL%*fO%M-!}=_4ePp|n z&Pmd&5@)&T#Hnc~nMv_F$#aw8n0sMEW^-fl7X{8#qR{kL0@L4DZO-nmy<)BT74G*i z)|&mzjQzy`i*+>CCqfrJ1>1ARuD z5$a4|UtmIFfDz&&M@PptVrKu$e6Zg4kaO+|?C-bxLX6voYsoBq8pJ=GDDlKQ>n!Ul z9qAnFuIZ|A_ch*miyyT5XZXDwb3PK(tykD%k=~PlT4`)1nr+jD7YP^zBsnZ{A-Oe^ zlM`-yqOk(k{yT1ShVFI0G9ZN2UJ1$G3#l%01@THR5pETt1tY9dZ`Gy=69g@$I4bz8 zlXI;3w&z;Bcc2s?FvRB=#&vQkHc6b}y@O_0W*BXz)0#3PBjZc6Ec-XCbN4pJ*((O% zhF`$p1~6cd1xb>!)19F0St4x9#1tCl*(O-M+?EnA5W=75hT%_yo8mWeIg;*&%5Y*t z+(``y!g)cK&#cLSkdYk|3vjEOu;*k|hG~{p%-UYXE-_s2z;;ytM+aqfPGznP@+Afg>v^e0{D=2}69y@v zmI=&R?*k(e=OY#cQ;k-NKubtr2EZnyi7`7y8ixcy@a;~gbHwk#p&{wiACIko@QS z!~lHZXmIXp*i_*2yi0U1!SBL^5(R;o<{f;27uBP@*GMP=NG(DlDHmb`RRz|4MS#hj z7|dKCPsTOJnrx>UQ-A@P;kaY#o2`D(@|AYGeem8gz~T#k7boonIq;NgU}F5+Gr{h` z1Y1hkG7@Z191Yt9HQL?Joj7gQYdihOYJfin$m9RK_~yJF$3%0Wm9n$oh;tG)A!Fh_ zGh-^r&B#RO1lY2bd&PjMsi`H9)@NvMS(d2#%HM?%d)R~?6p;D^g+1Un-f?6XBBZMz z-5sb^%us*T4Adij-CvCm=LhWWWQoBG%HT=e9w`h(nwh|zA)krln}`u;rC!tkYHYTR zC4mcq&rMEFF8)6mP^nb@rqgQ9$tpF84d4JkZqJ$SU1}?F& zKvWdCh~k67-FlmuUCmAv#_%lc$GxQ}de&KIEx_T>Bu)8-#U%_&R~R}kp{ElfJ%y

1hYSMbsYK_`(Y>YC&agAA0Da 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 RncV;Y002ovPDHLkV1m1mJPrT= literal 0 HcmV?d00001 diff --git a/public/images/add_release.png b/public/images/add_release.png new file mode 100644 index 0000000000000000000000000000000000000000..de920271a83ceaea95e529e65efadcd148bab3cd GIT binary patch literal 8061 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 LNkvXXu0mjff_}F{ literal 0 HcmV?d00001 diff --git a/public/javascripts/helpers/stories.js b/public/javascripts/helpers/stories.js index 967e891..1e336a4 100644 --- a/public/javascripts/helpers/stories.js +++ b/public/javascripts/helpers/stories.js @@ -3,11 +3,14 @@ Application.Helpers.Stories = { this._setupListeners(); }, - newForm: function(projectId,teamId){ + newForm: function(projectId,teamId,isRelease){ + var controller = 'stories' + if(isRelease) + controller = 'releases' if(projectId){ - var request_url = '/projects/'+ projectId + '/stories/new' + var request_url = '/projects/'+ projectId + '/' + controller + '/new' }else{ - var request_url = '/teams/'+ teamId + '/stories/new' + var request_url = '/teams/'+ teamId + '/' + controller + '/new' } // Request form new Ajax.Request(request_url, { @@ -151,7 +154,12 @@ Application.Helpers.Stories = { if(target.match('.new_story')){ projectId = target.readAttribute('data-project-id'); teamId = target.readAttribute('data-team-id'); - Stories.newForm(projectId,teamId); + Stories.newForm(projectId,teamId,false); + } + if(target.match('.new_release')){ + projectId = target.readAttribute('data-project-id'); + teamId = target.readAttribute('data-team-id'); + Stories.newForm(projectId,teamId,true); } // // Listener for remove story // if(target.match('.remove_story')){ diff --git a/public/stylesheets/sass/backlog.sass b/public/stylesheets/sass/backlog.sass index d66a974..4cee635 100644 --- a/public/stylesheets/sass/backlog.sass +++ b/public/stylesheets/sass/backlog.sass @@ -109,6 +109,8 @@ tr background: white &.finished background: #afc6e9 + &.release + background: #c8b7c4 .in_place_edit p diff --git a/public/stylesheets/sass/menu.sass b/public/stylesheets/sass/menu.sass index 5a38aa7..1412550 100644 --- a/public/stylesheets/sass/menu.sass +++ b/public/stylesheets/sass/menu.sass @@ -26,7 +26,7 @@ background: url("/images/export_backlog.png") no-repeat width: 86px height: 85px - left: 230px + left: 300px top: 9px .task-add :cursor move @@ -41,6 +41,12 @@ background: url("/images/add_story.png") no-repeat left: 145px top: 9px + .new_release + width: 81px + height: 80px + background: url("/images/add_release.png") no-repeat + left: 220px + top: 9px .dashboard background: url("/images/admin_section.png") no-repeat left: 225px diff --git a/test/unit/story_test.rb b/test/unit/story_test.rb index c987cdf..a9f2b88 100644 --- a/test/unit/story_test.rb +++ b/test/unit/story_test.rb @@ -25,7 +25,8 @@ class StoryTest < ActiveSupport::TestCase should_validate_presence_of :priority should_allow_values_for :priority, 0, 10, 20 should_not_allow_values_for :priority, "hola", "okaopsdgjko", "1 bla", "20 asdasd" - + + should_allow_values_for :release, true, false end context "When created" do