Commit 1b1e77c728e575a110e204e142e81bdff2737536

Authored by Dmitriy Zaporozhets
1 parent 4c1f435a

Issue Labels: Edit, show, index + filter

@@ -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"
@@ -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/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
@@ -139,6 +139,7 @@ class IssuesController < ApplicationController @@ -139,6 +139,7 @@ class IssuesController < ApplicationController
139 139
140 @issues = @issues.where(:assignee_id => params[:assignee_id]) if params[:assignee_id].present? 140 @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? 141 @issues = @issues.where(:milestone_id => params[:milestone_id]) if params[:milestone_id].present?
  142 + @issues = @issues.tagged_with(params[:label_name]) if params[:label_name].present?
142 @issues = @issues.includes(:author, :project).order("critical, updated_at") 143 @issues = @issues.includes(:author, :project).order("critical, updated_at")
143 @issues 144 @issues
144 end 145 end
app/helpers/issues_helper.rb
@@ -33,4 +33,8 @@ module IssuesHelper @@ -33,4 +33,8 @@ module IssuesHelper
33 classes << " today" if issue.today? 33 classes << " today" if issue.today?
34 classes 34 classes
35 end 35 end
  36 +
  37 + def issue_tags
  38 + @project.issues.tag_counts_on(:labels).map(&:name)
  39 + end
36 end 40 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"
app/views/issues/_form.html.haml
@@ -35,6 +35,12 @@ @@ -35,6 +35,12 @@
35 = f.text_area :description, :maxlength => 2000, :class => "xxlarge", :rows => 14 35 = f.text_area :description, :maxlength => 2000, :class => "xxlarge", :rows => 14
36 %p.hint Markdown is enabled. 36 %p.hint Markdown is enabled.
37 37
  38 + .clearfix
  39 + = f.label :label_list, "Labels"
  40 + .input
  41 + = f.text_field :label_list, :maxlength => 2000, :class => "xxlarge"
  42 + %p.hint Separate with comma.
  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/_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 + &nbsp;
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
@@ -31,28 +31,29 @@ @@ -31,28 +31,29 @@
31 31
32 %div#issues-table-holder.ui-box 32 %div#issues-table-holder.ui-box
33 .title 33 .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] 34 + .left
  35 + %ul.nav.nav-pills.left
  36 + %li{:class => ("active" if (params[:f] == "0" || !params[:f]))}
  37 + = link_to project_issues_path(@project, :f => 0, :milestone_id => params[:milestone_id]) do
  38 + Open
  39 + %li{:class => ("active" if params[:f] == "2")}
  40 + = link_to project_issues_path(@project, :f => 2, :milestone_id => params[:milestone_id]) do
  41 + Closed
  42 + %li{:class => ("active" if params[:f] == "3")}
  43 + = link_to project_issues_path(@project, :f => 3, :milestone_id => params[:milestone_id]) do
  44 + To Me
  45 + %li{:class => ("active" if params[:f] == "1")}
  46 + = link_to project_issues_path(@project, :f => 1, :milestone_id => params[:milestone_id]) do
  47 + All
55 48
  49 + .right
  50 + = form_tag project_issues_path(@project), :method => :get, :class => :right do
  51 + = select_tag(:label_name, options_for_select(issue_tags, params[:label_name]), :prompt => "Labels")
  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]
  55 + .clearfix
  56 +
56 %ul#issues-table.unstyled.issues_table 57 %ul#issues-table.unstyled.issues_table
57 = render "issues" 58 = render "issues"
58 59
@@ -60,9 +61,10 @@ @@ -60,9 +61,10 @@
60 $(function(){ 61 $(function(){
61 initIssuesSearch(); 62 initIssuesSearch();
62 setSortable(); 63 setSortable();
  64 + $("#label_name").chosen();
63 $("#assignee_id").chosen(); 65 $("#assignee_id").chosen();
64 $("#milestone_id").chosen(); 66 $("#milestone_id").chosen();
65 - $("#milestone_id, #assignee_id").live("change", function(){ 67 + $("#milestone_id, #assignee_id, #label_name").live("change", function(){
66 $(this).closest("form").submit(); 68 $(this).closest("form").submit();
67 }); 69 });
68 }) 70 })
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 + &nbsp;
57 59
58 - if @issue.description.present? 60 - if @issue.description.present?
59 .bottom_box_content 61 .bottom_box_content
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 +
features/step_definitions/project_issues_steps.rb 0 → 100644
@@ -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 +