Commit 7ef180608f87fc17f19cd66e91ae34487e5b6564
Exists in
master
and in
4 other branches
Merge branch 'feature/issue_tags' of dev.gitlabhq.com:gitlabhq
Showing
20 changed files
with
147 additions
and
99 deletions
Show diff stats
Gemfile
| @@ -29,7 +29,7 @@ gem "thin" | @@ -29,7 +29,7 @@ gem "thin" | ||
| 29 | gem "unicorn" | 29 | gem "unicorn" |
| 30 | gem "git" | 30 | gem "git" |
| 31 | gem "acts_as_list" | 31 | gem "acts_as_list" |
| 32 | -gem "acts-as-taggable-on", "~> 2.1.0" | 32 | +gem "acts-as-taggable-on", "2.3.1" |
| 33 | gem "drapper" | 33 | gem "drapper" |
| 34 | gem "resque", "~> 1.20.0" | 34 | gem "resque", "~> 1.20.0" |
| 35 | gem "httparty" | 35 | gem "httparty" |
Gemfile.lock
| @@ -89,8 +89,8 @@ GEM | @@ -89,8 +89,8 @@ GEM | ||
| 89 | activesupport (3.2.5) | 89 | activesupport (3.2.5) |
| 90 | i18n (~> 0.6) | 90 | i18n (~> 0.6) |
| 91 | multi_json (~> 1.0) | 91 | multi_json (~> 1.0) |
| 92 | - acts-as-taggable-on (2.1.1) | ||
| 93 | - rails | 92 | + acts-as-taggable-on (2.3.1) |
| 93 | + rails (~> 3.0) | ||
| 94 | acts_as_list (0.1.6) | 94 | acts_as_list (0.1.6) |
| 95 | addressable (2.2.8) | 95 | addressable (2.2.8) |
| 96 | ansi (1.4.2) | 96 | ansi (1.4.2) |
| @@ -351,7 +351,7 @@ PLATFORMS | @@ -351,7 +351,7 @@ PLATFORMS | ||
| 351 | ruby | 351 | ruby |
| 352 | 352 | ||
| 353 | DEPENDENCIES | 353 | DEPENDENCIES |
| 354 | - acts-as-taggable-on (~> 2.1.0) | 354 | + acts-as-taggable-on (= 2.3.1) |
| 355 | acts_as_list | 355 | acts_as_list |
| 356 | annotate! | 356 | annotate! |
| 357 | autotest | 357 | autotest |
app/assets/javascripts/issues.js
| @@ -61,3 +61,18 @@ function initIssuesSearch() { | @@ -61,3 +61,18 @@ function initIssuesSearch() { | ||
| 61 | $(this).closest('tr').fadeOut(); updatePage(); | 61 | $(this).closest('tr').fadeOut(); updatePage(); |
| 62 | }); | 62 | }); |
| 63 | } | 63 | } |
| 64 | + | ||
| 65 | +/** | ||
| 66 | + * Init issues page | ||
| 67 | + * | ||
| 68 | + */ | ||
| 69 | +function issuesPage(){ | ||
| 70 | + initIssuesSearch(); | ||
| 71 | + setSortable(); | ||
| 72 | + $("#label_name").chosen(); | ||
| 73 | + $("#assignee_id").chosen(); | ||
| 74 | + $("#milestone_id").chosen(); | ||
| 75 | + $("#milestone_id, #assignee_id, #label_name").on("change", function(){ | ||
| 76 | + $(this).closest("form").submit(); | ||
| 77 | + }); | ||
| 78 | +} |
app/assets/stylesheets/common.scss
| @@ -622,10 +622,6 @@ li.note { | @@ -622,10 +622,6 @@ li.note { | ||
| 622 | margin-right:5px; | 622 | margin-right:5px; |
| 623 | margin-top: 2px; | 623 | margin-top: 2px; |
| 624 | @include border-radius(4px); | 624 | @include border-radius(4px); |
| 625 | - &.critical { | ||
| 626 | - background: #EAA; | ||
| 627 | - border:1px solid #B88; | ||
| 628 | - } | ||
| 629 | &.today{ | 625 | &.today{ |
| 630 | background: #ADA; | 626 | background: #ADA; |
| 631 | border:1px solid #8B8; | 627 | border:1px solid #8B8; |
| @@ -664,14 +660,6 @@ li.note { | @@ -664,14 +660,6 @@ li.note { | ||
| 664 | } | 660 | } |
| 665 | } | 661 | } |
| 666 | 662 | ||
| 667 | - &.critical { | ||
| 668 | - background: #FEE; | ||
| 669 | - border-color:#ECC; | ||
| 670 | - .icon { | ||
| 671 | - background: #EAA; | ||
| 672 | - border:1px solid #B88; | ||
| 673 | - } | ||
| 674 | - } | ||
| 675 | &.today{ | 663 | &.today{ |
| 676 | background: #EFE; | 664 | background: #EFE; |
| 677 | border-color:#CEC; | 665 | border-color:#CEC; |
app/assets/stylesheets/gitlab_bootstrap.scss
| @@ -177,6 +177,14 @@ a:focus { | @@ -177,6 +177,14 @@ a:focus { | ||
| 177 | &.label-important { | 177 | &.label-important { |
| 178 | background-color: #B94A48; | 178 | background-color: #B94A48; |
| 179 | } | 179 | } |
| 180 | + | ||
| 181 | + &.label-issue { | ||
| 182 | + background-color: #eee; | ||
| 183 | + border: 1px solid #ccc; | ||
| 184 | + padding:4px 6px; | ||
| 185 | + color:#444; | ||
| 186 | + text-shadow:0 0 1px #fff; | ||
| 187 | + } | ||
| 180 | } | 188 | } |
| 181 | 189 | ||
| 182 | .nav-tabs > li > a, .nav-pills > li > a { | 190 | .nav-tabs > li > a, .nav-pills > li > a { |
app/controllers/issues_controller.rb
| @@ -3,6 +3,8 @@ class IssuesController < ApplicationController | @@ -3,6 +3,8 @@ class IssuesController < ApplicationController | ||
| 3 | before_filter :project | 3 | before_filter :project |
| 4 | before_filter :module_enabled | 4 | before_filter :module_enabled |
| 5 | before_filter :issue, :only => [:edit, :update, :destroy, :show] | 5 | before_filter :issue, :only => [:edit, :update, :destroy, :show] |
| 6 | + helper_method :issues_filter | ||
| 7 | + | ||
| 6 | layout "project" | 8 | layout "project" |
| 7 | 9 | ||
| 8 | # Authorize | 10 | # Authorize |
| @@ -130,16 +132,26 @@ class IssuesController < ApplicationController | @@ -130,16 +132,26 @@ class IssuesController < ApplicationController | ||
| 130 | end | 132 | end |
| 131 | 133 | ||
| 132 | def issues_filtered | 134 | def issues_filtered |
| 133 | - @issues = case params[:f].to_i | ||
| 134 | - when 1 then @project.issues | ||
| 135 | - when 2 then @project.issues.closed | ||
| 136 | - when 3 then @project.issues.opened.assigned(current_user) | 135 | + @issues = case params[:f] |
| 136 | + when issues_filter[:all] then @project.issues | ||
| 137 | + when issues_filter[:closed] then @project.issues.closed | ||
| 138 | + when issues_filter[:to_me] then @project.issues.opened.assigned(current_user) | ||
| 137 | else @project.issues.opened | 139 | else @project.issues.opened |
| 138 | end | 140 | end |
| 139 | 141 | ||
| 140 | @issues = @issues.where(:assignee_id => params[:assignee_id]) if params[:assignee_id].present? | 142 | @issues = @issues.where(:assignee_id => params[:assignee_id]) if params[:assignee_id].present? |
| 141 | @issues = @issues.where(:milestone_id => params[:milestone_id]) if params[:milestone_id].present? | 143 | @issues = @issues.where(:milestone_id => params[:milestone_id]) if params[:milestone_id].present? |
| 142 | - @issues = @issues.includes(:author, :project).order("critical, updated_at") | 144 | + @issues = @issues.tagged_with(params[:label_name]) if params[:label_name].present? |
| 145 | + @issues = @issues.includes(:author, :project).order("updated_at") | ||
| 143 | @issues | 146 | @issues |
| 144 | end | 147 | end |
| 148 | + | ||
| 149 | + def issues_filter | ||
| 150 | + { | ||
| 151 | + all: "1", | ||
| 152 | + closed: "2", | ||
| 153 | + to_me: "3", | ||
| 154 | + open: "0" | ||
| 155 | + } | ||
| 156 | + end | ||
| 145 | end | 157 | end |
app/controllers/merge_requests_controller.rb
| @@ -30,7 +30,7 @@ class MergeRequestsController < ApplicationController | @@ -30,7 +30,7 @@ class MergeRequestsController < ApplicationController | ||
| 30 | else @merge_requests.opened | 30 | else @merge_requests.opened |
| 31 | end.page(params[:page]).per(20) | 31 | end.page(params[:page]).per(20) |
| 32 | 32 | ||
| 33 | - @merge_requests = @merge_requests.includes(:author, :project).order("created_at desc") | 33 | + @merge_requests = @merge_requests.includes(:author, :project).order("closed, created_at desc") |
| 34 | end | 34 | end |
| 35 | 35 | ||
| 36 | def show | 36 | def show |
app/helpers/issues_helper.rb
| @@ -28,9 +28,12 @@ module IssuesHelper | @@ -28,9 +28,12 @@ module IssuesHelper | ||
| 28 | 28 | ||
| 29 | def issue_css_classes issue | 29 | def issue_css_classes issue |
| 30 | classes = "issue" | 30 | classes = "issue" |
| 31 | - classes << " critical" if issue.critical | ||
| 32 | classes << " closed" if issue.closed | 31 | classes << " closed" if issue.closed |
| 33 | classes << " today" if issue.today? | 32 | classes << " today" if issue.today? |
| 34 | classes | 33 | classes |
| 35 | end | 34 | end |
| 35 | + | ||
| 36 | + def issue_tags | ||
| 37 | + @project.issues.tag_counts_on(:labels).map(&:name) | ||
| 38 | + end | ||
| 36 | end | 39 | end |
app/models/issue.rb
| 1 | class Issue < ActiveRecord::Base | 1 | class Issue < ActiveRecord::Base |
| 2 | include Upvote | 2 | include Upvote |
| 3 | 3 | ||
| 4 | + acts_as_taggable_on :labels | ||
| 5 | + | ||
| 4 | belongs_to :project | 6 | belongs_to :project |
| 5 | belongs_to :milestone | 7 | belongs_to :milestone |
| 6 | belongs_to :author, :class_name => "User" | 8 | belongs_to :author, :class_name => "User" |
| @@ -31,9 +33,6 @@ class Issue < ActiveRecord::Base | @@ -31,9 +33,6 @@ class Issue < ActiveRecord::Base | ||
| 31 | validates :description, | 33 | validates :description, |
| 32 | :length => { :within => 0..2000 } | 34 | :length => { :within => 0..2000 } |
| 33 | 35 | ||
| 34 | - scope :critical, where(:critical => true) | ||
| 35 | - scope :non_critical, where(:critical => false) | ||
| 36 | - | ||
| 37 | scope :opened, where(:closed => false) | 36 | scope :opened, where(:closed => false) |
| 38 | scope :closed, where(:closed => true) | 37 | scope :closed, where(:closed => true) |
| 39 | scope :assigned, lambda { |u| where(:assignee_id => u.id)} | 38 | scope :assigned, lambda { |u| where(:assignee_id => u.id)} |
app/models/project.rb
| @@ -13,7 +13,7 @@ class Project < ActiveRecord::Base | @@ -13,7 +13,7 @@ class Project < ActiveRecord::Base | ||
| 13 | has_many :users, :through => :users_projects | 13 | has_many :users, :through => :users_projects |
| 14 | has_many :events, :dependent => :destroy | 14 | has_many :events, :dependent => :destroy |
| 15 | has_many :merge_requests, :dependent => :destroy | 15 | has_many :merge_requests, :dependent => :destroy |
| 16 | - has_many :issues, :dependent => :destroy, :order => "position" | 16 | + has_many :issues, :dependent => :destroy, :order => "closed, position" |
| 17 | has_many :milestones, :dependent => :destroy | 17 | has_many :milestones, :dependent => :destroy |
| 18 | has_many :users_projects, :dependent => :destroy | 18 | has_many :users_projects, :dependent => :destroy |
| 19 | has_many :notes, :dependent => :destroy | 19 | has_many :notes, :dependent => :destroy |
app/views/dashboard/issues.html.haml
| @@ -3,15 +3,6 @@ | @@ -3,15 +3,6 @@ | ||
| 3 | %small (assigned to you) | 3 | %small (assigned to you) |
| 4 | %small.right #{@issues.total_count} issues | 4 | %small.right #{@issues.total_count} issues |
| 5 | 5 | ||
| 6 | -%br | ||
| 7 | -.issues_legend | ||
| 8 | - .list_legend | ||
| 9 | - .icon.critical | ||
| 10 | - .text Critical | ||
| 11 | - | ||
| 12 | - .list_legend | ||
| 13 | - .icon.today | ||
| 14 | - .text Today | ||
| 15 | .clearfix | 6 | .clearfix |
| 16 | - if @issues.any? | 7 | - if @issues.any? |
| 17 | - @issues.group_by(&:project).each do |group| | 8 | - @issues.group_by(&:project).each do |group| |
app/views/issues/_form.html.haml
| @@ -9,32 +9,38 @@ | @@ -9,32 +9,38 @@ | ||
| 9 | .issue_form_box | 9 | .issue_form_box |
| 10 | .issue_title | 10 | .issue_title |
| 11 | .clearfix | 11 | .clearfix |
| 12 | - = f.label :title, "Issue Subject *" | 12 | + = f.label :title do |
| 13 | + %strong= "Subject *" | ||
| 13 | .input | 14 | .input |
| 14 | = f.text_field :title, :maxlength => 255, :class => "xxlarge" | 15 | = f.text_field :title, :maxlength => 255, :class => "xxlarge" |
| 15 | .issue_middle_block | 16 | .issue_middle_block |
| 16 | .issue_assignee | 17 | .issue_assignee |
| 17 | - = f.label :assignee_id, "Assign to" | ||
| 18 | - .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { :include_blank => "Assign to user" }) | 18 | + = f.label :assignee_id do |
| 19 | + %i.icon-user | ||
| 20 | + Assign to | ||
| 21 | + .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { :include_blank => "Select a user" }) | ||
| 19 | .issue_milestone | 22 | .issue_milestone |
| 20 | - = f.label :milestone_id | 23 | + = f.label :milestone_id do |
| 24 | + %i.icon-time | ||
| 25 | + Milestone | ||
| 21 | .input= f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { :include_blank => "Select milestone" }) | 26 | .input= f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { :include_blank => "Select milestone" }) |
| 22 | 27 | ||
| 23 | .issue_description | 28 | .issue_description |
| 24 | .clearfix | 29 | .clearfix |
| 25 | - = f.label :critical, "Critical" | ||
| 26 | - .input= f.check_box :critical | 30 | + = f.label :label_list do |
| 31 | + %i.icon-tag | ||
| 32 | + Labels | ||
| 33 | + .input | ||
| 34 | + = f.text_field :label_list, :maxlength => 2000, :class => "xxlarge" | ||
| 35 | + %p.hint Separate with comma. | ||
| 27 | 36 | ||
| 28 | - - unless @issue.new_record? | ||
| 29 | - .clearfix | ||
| 30 | - = f.label :closed | ||
| 31 | - .input= f.check_box :closed | ||
| 32 | .clearfix | 37 | .clearfix |
| 33 | - = f.label :description, "Issue Details" | 38 | + = f.label :description, "Details" |
| 34 | .input | 39 | .input |
| 35 | = f.text_area :description, :maxlength => 2000, :class => "xxlarge", :rows => 14 | 40 | = f.text_area :description, :maxlength => 2000, :class => "xxlarge", :rows => 14 |
| 36 | %p.hint Markdown is enabled. | 41 | %p.hint Markdown is enabled. |
| 37 | 42 | ||
| 43 | + | ||
| 38 | .actions | 44 | .actions |
| 39 | - if @issue.new_record? | 45 | - if @issue.new_record? |
| 40 | = f.submit 'Submit new issue', :class => "primary btn" | 46 | = f.submit 'Submit new issue', :class => "primary btn" |
app/views/issues/_issues.html.haml
| 1 | -- @issues.select(&:critical).each do |issue| | ||
| 2 | - = render(:partial => 'issues/show', :locals => {:issue => issue}) | ||
| 3 | - | ||
| 4 | -- @issues.reject(&:critical).each do |issue| | 1 | +- @issues.each do |issue| |
| 5 | = render(:partial => 'issues/show', :locals => {:issue => issue}) | 2 | = render(:partial => 'issues/show', :locals => {:issue => issue}) |
| 6 | 3 | ||
| 7 | - if @issues.present? | 4 | - if @issues.present? |
app/views/issues/_show.html.haml
| @@ -2,6 +2,11 @@ | @@ -2,6 +2,11 @@ | ||
| 2 | .list_legend | 2 | .list_legend |
| 3 | .icon | 3 | .icon |
| 4 | .right | 4 | .right |
| 5 | + - issue.labels.each do |label| | ||
| 6 | + %span.label.label-issue | ||
| 7 | + %i.icon-tag | ||
| 8 | + = label.name | ||
| 9 | + | ||
| 5 | - if issue.notes.any? | 10 | - if issue.notes.any? |
| 6 | %span.btn.small.disabled.padded | 11 | %span.btn.small.disabled.padded |
| 7 | %i.icon-comment | 12 | %i.icon-comment |
app/views/issues/index.html.haml
| @@ -13,58 +13,38 @@ | @@ -13,58 +13,38 @@ | ||
| 13 | = hidden_field_tag :status, params[:f] | 13 | = hidden_field_tag :status, params[:f] |
| 14 | = search_field_tag :issue_search, nil, { :placeholder => 'Search', :class => 'issue_search span3 right neib' } | 14 | = search_field_tag :issue_search, nil, { :placeholder => 'Search', :class => 'issue_search span3 right neib' } |
| 15 | 15 | ||
| 16 | - %br | ||
| 17 | - | ||
| 18 | - .issues_legend | ||
| 19 | - .list_legend | ||
| 20 | - .icon.today | ||
| 21 | - .text Today | ||
| 22 | - | ||
| 23 | - .list_legend | ||
| 24 | - .icon.critical | ||
| 25 | - .text Critical | ||
| 26 | - | ||
| 27 | - .list_legend | ||
| 28 | - .icon.closed | ||
| 29 | - .text Closed | ||
| 30 | .clearfix | 16 | .clearfix |
| 31 | - | ||
| 32 | %div#issues-table-holder.ui-box | 17 | %div#issues-table-holder.ui-box |
| 33 | .title | 18 | .title |
| 34 | - .row | ||
| 35 | - .span4 | ||
| 36 | - %ul.nav.nav-pills.left | ||
| 37 | - %li{:class => ("active" if (params[:f] == "0" || !params[:f]))} | ||
| 38 | - = link_to project_issues_path(@project, :f => 0, :milestone_id => params[:milestone_id]) do | ||
| 39 | - Open | ||
| 40 | - %li{:class => ("active" if params[:f] == "2")} | ||
| 41 | - = link_to project_issues_path(@project, :f => 2, :milestone_id => params[:milestone_id]) do | ||
| 42 | - Closed | ||
| 43 | - %li{:class => ("active" if params[:f] == "3")} | ||
| 44 | - = link_to project_issues_path(@project, :f => 3, :milestone_id => params[:milestone_id]) do | ||
| 45 | - To Me | ||
| 46 | - %li{:class => ("active" if params[:f] == "1")} | ||
| 47 | - = link_to project_issues_path(@project, :f => 1, :milestone_id => params[:milestone_id]) do | ||
| 48 | - All | ||
| 49 | - | ||
| 50 | - .span6.right | ||
| 51 | - = form_tag project_issues_path(@project), :method => :get, :class => :right do | ||
| 52 | - = select_tag(:assignee_id, options_from_collection_for_select(@project.users.all, "id", "name", params[:assignee_id]), :prompt => "Assignee") | ||
| 53 | - = select_tag(:milestone_id, options_from_collection_for_select(@project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), :prompt => "Milestone") | ||
| 54 | - = hidden_field_tag :f, params[:f] | 19 | + .left |
| 20 | + %ul.nav.nav-pills.left | ||
| 21 | + %li{:class => ("active" if (params[:f] == issues_filter[:open] || !params[:f]))} | ||
| 22 | + = link_to project_issues_path(@project, :f => issues_filter[:open], :milestone_id => params[:milestone_id]) do | ||
| 23 | + Open | ||
| 24 | + %li{:class => ("active" if params[:f] == issues_filter[:closed])} | ||
| 25 | + = link_to project_issues_path(@project, :f => issues_filter[:closed], :milestone_id => params[:milestone_id]) do | ||
| 26 | + Closed | ||
| 27 | + %li{:class => ("active" if params[:f] == issues_filter[:to_me])} | ||
| 28 | + = link_to project_issues_path(@project, :f => issues_filter[:to_me], :milestone_id => params[:milestone_id]) do | ||
| 29 | + To Me | ||
| 30 | + %li{:class => ("active" if params[:f] == issues_filter[:all])} | ||
| 31 | + = link_to project_issues_path(@project, :f => issues_filter[:all], :milestone_id => params[:milestone_id]) do | ||
| 32 | + All | ||
| 55 | 33 | ||
| 34 | + .right | ||
| 35 | + = form_tag project_issues_path(@project), :method => :get, :class => :right do | ||
| 36 | + = select_tag(:label_name, options_for_select(issue_tags, params[:label_name]), :prompt => "Labels") | ||
| 37 | + = select_tag(:assignee_id, options_from_collection_for_select(@project.users.all, "id", "name", params[:assignee_id]), :prompt => "Assignee") | ||
| 38 | + = select_tag(:milestone_id, options_from_collection_for_select(@project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), :prompt => "Milestone") | ||
| 39 | + = hidden_field_tag :f, params[:f] | ||
| 40 | + .clearfix | ||
| 41 | + | ||
| 56 | %ul#issues-table.unstyled.issues_table | 42 | %ul#issues-table.unstyled.issues_table |
| 57 | = render "issues" | 43 | = render "issues" |
| 58 | 44 | ||
| 59 | :javascript | 45 | :javascript |
| 60 | $(function(){ | 46 | $(function(){ |
| 61 | - initIssuesSearch(); | ||
| 62 | - setSortable(); | ||
| 63 | - $("#assignee_id").chosen(); | ||
| 64 | - $("#milestone_id").chosen(); | ||
| 65 | - $("#milestone_id, #assignee_id").live("change", function(){ | ||
| 66 | - $(this).closest("form").submit(); | ||
| 67 | - }); | 47 | + issuesPage(); |
| 68 | }) | 48 | }) |
| 69 | 49 | ||
| 70 | function setSortable(){ | 50 | function setSortable(){ |
app/views/issues/show.html.haml
| @@ -51,9 +51,11 @@ | @@ -51,9 +51,11 @@ | ||
| 51 | = truncate(milestone.title, :length => 20) | 51 | = truncate(milestone.title, :length => 20) |
| 52 | 52 | ||
| 53 | .right | 53 | .right |
| 54 | - - if @issue.critical | ||
| 55 | - %span.label.label-important | ||
| 56 | - Critical | 54 | + - @issue.labels.each do |label| |
| 55 | + %span.label.label-issue | ||
| 56 | + %i.icon-tag | ||
| 57 | + = label.name | ||
| 58 | + | ||
| 57 | 59 | ||
| 58 | - if @issue.description.present? | 60 | - if @issue.description.present? |
| 59 | .bottom_box_content | 61 | .bottom_box_content |
db/schema.rb
| @@ -11,7 +11,7 @@ | @@ -11,7 +11,7 @@ | ||
| 11 | # | 11 | # |
| 12 | # It's strongly recommended to check this file into your version control system. | 12 | # It's strongly recommended to check this file into your version control system. |
| 13 | 13 | ||
| 14 | -ActiveRecord::Schema.define(:version => 20120413135904) do | 14 | +ActiveRecord::Schema.define(:version => 20120627145613) do |
| 15 | 15 | ||
| 16 | create_table "events", :force => true do |t| | 16 | create_table "events", :force => true do |t| |
| 17 | t.string "target_type" | 17 | t.string "target_type" |
| @@ -34,7 +34,6 @@ ActiveRecord::Schema.define(:version => 20120413135904) do | @@ -34,7 +34,6 @@ ActiveRecord::Schema.define(:version => 20120413135904) do | ||
| 34 | t.datetime "updated_at", :null => false | 34 | t.datetime "updated_at", :null => false |
| 35 | t.boolean "closed", :default => false, :null => false | 35 | t.boolean "closed", :default => false, :null => false |
| 36 | t.integer "position", :default => 0 | 36 | t.integer "position", :default => 0 |
| 37 | - t.boolean "critical", :default => false, :null => false | ||
| 38 | t.string "branch_name" | 37 | t.string "branch_name" |
| 39 | t.text "description" | 38 | t.text "description" |
| 40 | t.integer "milestone_id" | 39 | t.integer "milestone_id" |
features/projects/issues/issues.feature
| @@ -0,0 +1,12 @@ | @@ -0,0 +1,12 @@ | ||
| 1 | +Feature: Issues | ||
| 2 | + Background: | ||
| 3 | + Given I signin as a user | ||
| 4 | + And I own project "Shop" | ||
| 5 | + And project "Shop" have "Release 0.4" open issue | ||
| 6 | + And project "Shop" have "Release 0.3" closed issue | ||
| 7 | + And I visit project "Shop" issues page | ||
| 8 | + | ||
| 9 | + Scenario: I should see open issues | ||
| 10 | + Given I should see "Release 0.4" open issue | ||
| 11 | + And I should not see "Release 0.3" closed issue | ||
| 12 | + |
| @@ -0,0 +1,22 @@ | @@ -0,0 +1,22 @@ | ||
| 1 | +Given /^project "(.*?)" have "(.*?)" open issue$/ do |arg1, arg2| | ||
| 2 | + project = Project.find_by_name(arg1) | ||
| 3 | + Factory.create(:issue, :title => arg2, :project => project, :author => project.users.first) | ||
| 4 | +end | ||
| 5 | + | ||
| 6 | +Given /^project "(.*?)" have "(.*?)" closed issue$/ do |arg1, arg2| | ||
| 7 | + project = Project.find_by_name(arg1) | ||
| 8 | + Factory.create(:issue, :title => arg2, :project => project, :author => project.users.first, :closed => true) | ||
| 9 | +end | ||
| 10 | + | ||
| 11 | +Given /^I visit project "(.*?)" issues page$/ do |arg1| | ||
| 12 | + visit project_issues_path(Project.find_by_name(arg1)) | ||
| 13 | +end | ||
| 14 | + | ||
| 15 | +Given /^I should see "(.*?)" open issue$/ do |arg1| | ||
| 16 | + page.should have_content arg1 | ||
| 17 | +end | ||
| 18 | + | ||
| 19 | +Given /^I should not see "(.*?)" closed issue$/ do |arg1| | ||
| 20 | + page.should_not have_content arg1 | ||
| 21 | +end | ||
| 22 | + |