Commit 2f7effe804bdae9fca4ca0bb55c841664c2de978

Authored by Dmitriy Zaporozhets
1 parent 88260774

Refactor issues, Remove ajax

app/assets/javascripts/issues.js
1 -function switchToNewIssue(){  
2 - $(".issues_content").hide("fade", { direction: "left" }, 150, function(){  
3 - $('select#issue_assignee_id').chosen();  
4 - $('select#issue_milestone_id').chosen();  
5 - $("#new_issue_dialog").show("fade", { direction: "right" }, 150);  
6 - $('.top-tabs .add_new').hide();  
7 - disableButtonIfEmptyField("#issue_title", ".save-btn");  
8 - GitLab.GfmAutoComplete.setup();  
9 - });  
10 -}  
11 -  
12 -function switchToEditIssue(){  
13 - $(".issues_content").hide("fade", { direction: "left" }, 150, function(){  
14 - $('select#issue_assignee_id').chosen();  
15 - $('select#issue_milestone_id').chosen();  
16 - $("#edit_issue_dialog").show("fade", { direction: "right" }, 150);  
17 - $('.add_new').hide();  
18 - disableButtonIfEmptyField("#issue_title", ".save-btn");  
19 - GitLab.GfmAutoComplete.setup();  
20 - });  
21 -}  
22 -  
23 -function switchFromNewIssue(){  
24 - backToIssues();  
25 -}  
26 -  
27 -function switchFromEditIssue(){  
28 - backToIssues();  
29 -}  
30 -  
31 -function backToIssues(){  
32 - $("#edit_issue_dialog, #new_issue_dialog").hide("fade", { direction: "right" }, 150, function(){  
33 - $(".issues_content").show("fade", { direction: "left" }, 150, function() {  
34 - $("#edit_issue_dialog").html("");  
35 - $("#new_issue_dialog").html("");  
36 - $('.add_new').show();  
37 - });  
38 - });  
39 -}  
40 -  
41 function initIssuesSearch() { 1 function initIssuesSearch() {
42 var href = $('#issue_search_form').attr('action'); 2 var href = $('#issue_search_form').attr('action');
43 var last_terms = ''; 3 var last_terms = '';
@@ -76,23 +36,15 @@ function issuesPage(){ @@ -76,23 +36,15 @@ function issuesPage(){
76 $(this).closest("form").submit(); 36 $(this).closest("form").submit();
77 }); 37 });
78 38
79 - $("#new_issue_link").click(function(){  
80 - updateNewIssueURL();  
81 - });  
82 -  
83 - $('body').on('ajax:success', '.close_issue, .reopen_issue, #new_issue', function(){ 39 + $('body').on('ajax:success', '.close_issue, .reopen_issue', function(){
84 var t = $(this), 40 var t = $(this),
85 totalIssues, 41 totalIssues,
86 - reopen = t.hasClass('reopen_issue'),  
87 - newIssue = false;  
88 - if( this.id == 'new_issue' ){  
89 - newIssue = true;  
90 - }  
91 - $('.issue_counter, #new_issue').each(function(){ 42 + reopen = t.hasClass('reopen_issue');
  43 + $('.issue_counter').each(function(){
92 var issue = $(this); 44 var issue = $(this);
93 totalIssues = parseInt( $(this).html(), 10 ); 45 totalIssues = parseInt( $(this).html(), 10 );
94 46
95 - if( newIssue || ( reopen && issue.closest('.main_menu').length ) ){ 47 + if( reopen && issue.closest('.main_menu').length ){
96 $(this).html( totalIssues+1 ); 48 $(this).html( totalIssues+1 );
97 }else { 49 }else {
98 $(this).html( totalIssues-1 ); 50 $(this).html( totalIssues-1 );
@@ -126,20 +78,3 @@ function issuesCheckChanged() { @@ -126,20 +78,3 @@ function issuesCheckChanged() {
126 $('.issues_filters').show(); 78 $('.issues_filters').show();
127 } 79 }
128 } 80 }
129 -  
130 -function updateNewIssueURL(){  
131 - var new_issue_link = $("#new_issue_link");  
132 - var milestone_id = $("#milestone_id").val();  
133 - var assignee_id = $("#assignee_id").val();  
134 - var new_href = "";  
135 - if(milestone_id){  
136 - new_href = "issue[milestone_id]=" + milestone_id + "&";  
137 - }  
138 - if(assignee_id){  
139 - new_href = new_href + "issue[assignee_id]=" + assignee_id;  
140 - }  
141 - if(new_href.length){  
142 - new_href = new_issue_link.attr("href") + "?" + new_href;  
143 - new_issue_link.attr("href", new_href);  
144 - }  
145 -};  
app/controllers/issues_controller.rb
1 class IssuesController < ProjectResourceController 1 class IssuesController < ProjectResourceController
2 before_filter :module_enabled 2 before_filter :module_enabled
3 - before_filter :issue, only: [:edit, :update, :destroy, :show] 3 + before_filter :issue, only: [:edit, :update, :show]
4 4
5 # Allow read any issue 5 # Allow read any issue
6 before_filter :authorize_read_issue! 6 before_filter :authorize_read_issue!
@@ -11,9 +11,6 @@ class IssuesController &lt; ProjectResourceController @@ -11,9 +11,6 @@ class IssuesController &lt; ProjectResourceController
11 # Allow modify issue 11 # Allow modify issue
12 before_filter :authorize_modify_issue!, only: [:edit, :update] 12 before_filter :authorize_modify_issue!, only: [:edit, :update]
13 13
14 - # Allow destroy issue  
15 - before_filter :authorize_admin_issue!, only: [:destroy]  
16 -  
17 respond_to :js, :html 14 respond_to :js, :html
18 15
19 def index 16 def index
@@ -77,15 +74,6 @@ class IssuesController &lt; ProjectResourceController @@ -77,15 +74,6 @@ class IssuesController &lt; ProjectResourceController
77 end 74 end
78 end 75 end
79 76
80 - def destroy  
81 - @issue.destroy  
82 -  
83 - respond_to do |format|  
84 - format.html { redirect_to project_issues_path }  
85 - format.js { render nothing: true }  
86 - end  
87 - end  
88 -  
89 def sort 77 def sort
90 return render_404 unless can?(current_user, :admin_issue, @project) 78 return render_404 unless can?(current_user, :admin_issue, @project)
91 79
app/controllers/merge_requests_controller.rb
1 class MergeRequestsController < ProjectResourceController 1 class MergeRequestsController < ProjectResourceController
2 before_filter :module_enabled 2 before_filter :module_enabled
3 - before_filter :merge_request, only: [:edit, :update, :destroy, :show, :commits, :diffs, :automerge, :automerge_check, :ci_status] 3 + before_filter :merge_request, only: [:edit, :update, :show, :commits, :diffs, :automerge, :automerge_check, :ci_status]
4 before_filter :validates_merge_request, only: [:show, :diffs] 4 before_filter :validates_merge_request, only: [:show, :diffs]
5 before_filter :define_show_vars, only: [:show, :diffs] 5 before_filter :define_show_vars, only: [:show, :diffs]
6 6
@@ -13,9 +13,6 @@ class MergeRequestsController &lt; ProjectResourceController @@ -13,9 +13,6 @@ class MergeRequestsController &lt; ProjectResourceController
13 # Allow modify merge_request 13 # Allow modify merge_request
14 before_filter :authorize_modify_merge_request!, only: [:close, :edit, :update, :sort] 14 before_filter :authorize_modify_merge_request!, only: [:close, :edit, :update, :sort]
15 15
16 - # Allow destroy merge_request  
17 - before_filter :authorize_admin_merge_request!, only: [:destroy]  
18 -  
19 def index 16 def index
20 @merge_requests = MergeRequestsLoadContext.new(project, current_user, params).execute 17 @merge_requests = MergeRequestsLoadContext.new(project, current_user, params).execute
21 end 18 end
@@ -85,14 +82,6 @@ class MergeRequestsController &lt; ProjectResourceController @@ -85,14 +82,6 @@ class MergeRequestsController &lt; ProjectResourceController
85 end 82 end
86 end 83 end
87 84
88 - def destroy  
89 - @merge_request.destroy  
90 -  
91 - respond_to do |format|  
92 - format.html { redirect_to project_merge_requests_url(@project) }  
93 - end  
94 - end  
95 -  
96 def branch_from 85 def branch_from
97 @commit = project.commit(params[:ref]) 86 @commit = project.commit(params[:ref])
98 @commit = CommitDecorator.decorate(@commit) 87 @commit = CommitDecorator.decorate(@commit)
app/models/milestone.rb
@@ -62,7 +62,11 @@ class Milestone &lt; ActiveRecord::Base @@ -62,7 +62,11 @@ class Milestone &lt; ActiveRecord::Base
62 end 62 end
63 63
64 def can_be_closed? 64 def can_be_closed?
65 - issues.count > 0 && open? && issues.opened.count.zero? 65 + open? && issues.opened.count.zero?
  66 + end
  67 +
  68 + def is_empty?
  69 + total_items_count.zero?
66 end 70 end
67 71
68 def open? 72 def open?
app/views/issues/_form.html.haml
1 %div.issue-form-holder 1 %div.issue-form-holder
2 %h3.page_title= @issue.new_record? ? "New Issue" : "Edit Issue ##{@issue.id}" 2 %h3.page_title= @issue.new_record? ? "New Issue" : "Edit Issue ##{@issue.id}"
3 - = form_for [@project, @issue], remote: request.xhr? do |f| 3 + = form_for [@project, @issue] do |f|
4 -if @issue.errors.any? 4 -if @issue.errors.any?
5 .alert-message.block-message.error 5 .alert-message.block-message.error
6 - %ul  
7 - - @issue.errors.full_messages.each do |msg|  
8 - %li= msg 6 + - @issue.errors.full_messages.each do |msg|
  7 + %span= msg
  8 + %br
9 .issue_form_box 9 .issue_form_box
10 .issue_title 10 .issue_title
11 .clearfix 11 .clearfix
12 = f.label :title do 12 = f.label :title do
13 %strong= "Subject *" 13 %strong= "Subject *"
14 .input 14 .input
15 - = f.text_field :title, maxlength: 255, class: "xxlarge js-gfm-input", autofocus: true 15 + = f.text_field :title, maxlength: 255, class: "xxlarge js-gfm-input", autofocus: true, required: true
16 .issue_middle_block 16 .issue_middle_block
17 .issue_assignee 17 .issue_assignee
18 = f.label :assignee_id do 18 = f.label :assignee_id do
@@ -47,14 +47,8 @@ @@ -47,14 +47,8 @@
47 -else 47 -else
48 = f.submit 'Save changes', class: "save-btn btn" 48 = f.submit 'Save changes', class: "save-btn btn"
49 49
50 - - cancel_class = 'btn cancel-btn'  
51 - - if request.xhr?  
52 - = link_to "Cancel", "#back", onclick: "backToIssues();", class: cancel_class  
53 - - else  
54 - - if @issue.new_record?  
55 - = link_to "Cancel", project_issues_path(@project), class: cancel_class  
56 - - else  
57 - = link_to "Cancel", project_issue_path(@project, @issue), class: cancel_class 50 + - cancel_path = @issue.new_record? ? project_issues_path(@project) : project_issue_path(@project, @issue)
  51 + = link_to "Cancel", cancel_path, class: 'btn cancel-btn'
58 52
59 53
60 54
app/views/issues/_show.html.haml
@@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
16 = link_to 'Reopen', project_issue_path(issue.project, issue, issue: {closed: false }, status_only: true), method: :put, class: "btn small grouped reopen_issue", remote: true 16 = link_to 'Reopen', project_issue_path(issue.project, issue, issue: {closed: false }, status_only: true), method: :put, class: "btn small grouped reopen_issue", remote: true
17 - else 17 - else
18 = link_to 'Close', project_issue_path(issue.project, issue, issue: {closed: true }, status_only: true), method: :put, class: "btn small grouped close_issue", remote: true 18 = link_to 'Close', project_issue_path(issue.project, issue, issue: {closed: true }, status_only: true), method: :put, class: "btn small grouped close_issue", remote: true
19 - = link_to edit_project_issue_path(issue.project, issue), class: "btn small edit-issue-link grouped", remote: true do 19 + = link_to edit_project_issue_path(issue.project, issue), class: "btn small edit-issue-link grouped" do
20 %i.icon-edit 20 %i.icon-edit
21 Edit 21 Edit
22 22
app/views/issues/create.js.haml
@@ -1,10 +0,0 @@ @@ -1,10 +0,0 @@
1 -- if @issue.valid?  
2 - :plain  
3 - switchFromNewIssue();  
4 - $("#issues-table").prepend("#{escape_javascript(render(partial: 'show', locals: {issue: @issue}))}");  
5 - $.ajax({type: "GET", url: location.href, dataType: "script"});  
6 -- else  
7 - :plain  
8 - $("#new_issue_dialog").empty();  
9 - $("#new_issue_dialog").append("#{escape_javascript(render('form'))}");  
10 - $('select#issue_assignee_id').chosen();  
app/views/issues/edit.js.haml
@@ -1,4 +0,0 @@ @@ -1,4 +0,0 @@
1 -:plain  
2 - $("#edit_issue_dialog").html("#{escape_javascript(render('form'))}");  
3 - switchToEditIssue();  
4 -  
app/views/issues/index.html.haml
1 = render "issues/head" 1 = render "issues/head"
  2 +#new_issue_dialog
  3 +#edit_issue_dialog
2 .issues_content 4 .issues_content
3 %h3.page_title 5 %h3.page_title
4 Issues 6 Issues
@@ -6,7 +8,7 @@ @@ -6,7 +8,7 @@
6 .right 8 .right
7 .span5 9 .span5
8 - if can? current_user, :write_issue, @project 10 - if can? current_user, :write_issue, @project
9 - = link_to new_project_issue_path(@project), class: "right btn", title: "New Issue", remote: true, id: "new_issue_link" do 11 + = link_to new_project_issue_path(@project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "right btn", title: "New Issue", id: "new_issue_link" do
10 %i.icon-plus 12 %i.icon-plus
11 New Issue 13 New Issue
12 = form_tag search_project_issues_path(@project), method: :get, remote: true, id: "issue_search_form", class: :right do 14 = form_tag search_project_issues_path(@project), method: :get, remote: true, id: "issue_search_form", class: :right do
@@ -58,9 +60,6 @@ @@ -58,9 +60,6 @@
58 %ul#issues-table.well-list.issues_table 60 %ul#issues-table.well-list.issues_table
59 = render "issues" 61 = render "issues"
60 62
61 -#new_issue_dialog  
62 -#edit_issue_dialog  
63 -  
64 :javascript 63 :javascript
65 $(function(){ 64 $(function(){
66 issuesPage(); 65 issuesPage();
app/views/issues/new.js.haml
@@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
1 -:plain  
2 - $("#new_issue_dialog").html("#{escape_javascript(render('form'))}");  
3 - switchToNewIssue();  
app/views/issues/update.js.haml
@@ -1,14 +0,0 @@ @@ -1,14 +0,0 @@
1 -- if params[:status_only]  
2 - - if @issue.valid?  
3 - :plain  
4 - $("##{dom_id(@issue)}").fadeOut();  
5 -- else  
6 - - if @issue.valid?  
7 - :plain  
8 - updatePage();  
9 - switchFromEditIssue();  
10 - - else  
11 - :plain  
12 - $("#edit_issue_dialog").empty();  
13 - $("#edit_issue_dialog").append("#{escape_javascript(render('form'))}");  
14 - $('select#issue_assignee_id').chosen();  
app/views/merge_requests/_form.html.haml
@@ -32,7 +32,7 @@ @@ -32,7 +32,7 @@
32 .top_box_content 32 .top_box_content
33 = f.label :title do 33 = f.label :title do
34 %strong= "Title *" 34 %strong= "Title *"
35 - .input= f.text_field :title, class: "input-xxlarge pad js-gfm-input", maxlength: 255, rows: 5 35 + .input= f.text_field :title, class: "input-xxlarge pad js-gfm-input", maxlength: 255, rows: 5, required: true
36 .merge_requests_middle_box 36 .merge_requests_middle_box
37 .merge_requests_assignee 37 .merge_requests_assignee
38 = f.label :assignee_id do 38 = f.label :assignee_id do
app/views/milestones/_milestone.html.haml
@@ -10,15 +10,18 @@ @@ -10,15 +10,18 @@
10 %span.cred (Expired) 10 %span.cred (Expired)
11 %small 11 %small
12 = milestone.expires_at 12 = milestone.expires_at
13 - .row  
14 - .span4  
15 - .progress.progress-info  
16 - .bar{style: "width: #{milestone.percent_complete}%;"}  
17 - .span6  
18 - = link_to project_issues_path(milestone.project, milestone_id: milestone.id) do  
19 - = pluralize milestone.issues.count, 'Issue'  
20 - &nbsp;  
21 - = link_to project_merge_requests_path(milestone.project, milestone_id: milestone.id) do  
22 - = pluralize milestone.merge_requests.count, 'Merge Request'  
23 - &nbsp;  
24 - %span.light #{milestone.percent_complete}% complete 13 + - if milestone.is_empty?
  14 + %span.muted Empty
  15 + - else
  16 + .row
  17 + .span4
  18 + .progress.progress-info
  19 + .bar{style: "width: #{milestone.percent_complete}%;"}
  20 + .span6
  21 + = link_to project_issues_path(milestone.project, milestone_id: milestone.id) do
  22 + = pluralize milestone.issues.count, 'Issue'
  23 + &nbsp;
  24 + = link_to project_merge_requests_path(milestone.project, milestone_id: milestone.id) do
  25 + = pluralize milestone.merge_requests.count, 'Merge Request'
  26 + &nbsp;
  27 + %span.light #{milestone.percent_complete}% complete
config/routes.rb
@@ -164,7 +164,7 @@ Gitlab::Application.routes.draw do @@ -164,7 +164,7 @@ Gitlab::Application.routes.draw do
164 end 164 end
165 end 165 end
166 166
167 - resources :merge_requests, constraints: {id: /\d+/} do 167 + resources :merge_requests, constraints: {id: /\d+/}, except: [:destroy] do
168 member do 168 member do
169 get :diffs 169 get :diffs
170 get :automerge 170 get :automerge
@@ -200,9 +200,9 @@ Gitlab::Application.routes.draw do @@ -200,9 +200,9 @@ Gitlab::Application.routes.draw do
200 :via => [:get, :post], constraints: {from: /.+/, to: /.+/} 200 :via => [:get, :post], constraints: {from: /.+/, to: /.+/}
201 201
202 resources :team, controller: 'team_members', only: [:index] 202 resources :team, controller: 'team_members', only: [:index]
203 - resources :milestones 203 + resources :milestones, except: [:destroy]
204 resources :labels, only: [:index] 204 resources :labels, only: [:index]
205 - resources :issues do 205 + resources :issues, except: [:destroy] do
206 collection do 206 collection do
207 post :sort 207 post :sort
208 post :bulk_update 208 post :bulk_update
features/project/issues/issues.feature
@@ -24,11 +24,9 @@ Feature: Project Issues @@ -24,11 +24,9 @@ Feature: Project Issues
24 Given I click link "Release 0.4" 24 Given I click link "Release 0.4"
25 Then I should see issue "Release 0.4" 25 Then I should see issue "Release 0.4"
26 26
27 - @javascript  
28 Scenario: I submit new unassigned issue 27 Scenario: I submit new unassigned issue
29 Given I click link "New Issue" 28 Given I click link "New Issue"
30 And I submit new issue "500 error on profile" 29 And I submit new issue "500 error on profile"
31 - Given I click link "500 error on profile"  
32 Then I should see issue "500 error on profile" 30 Then I should see issue "500 error on profile"
33 31
34 @javascript 32 @javascript
@@ -57,15 +55,6 @@ Feature: Project Issues @@ -57,15 +55,6 @@ Feature: Project Issues
57 Then I should see "Release 0.3" in issues 55 Then I should see "Release 0.3" in issues
58 And I should not see "Release 0.4" in issues 56 And I should not see "Release 0.4" in issues
59 57
60 - # TODO: find out solution for poltergeist/phantomjs or remove  
61 - # @javascript  
62 - # Scenario: I clear search  
63 - # Given I click link "All"  
64 - # And I fill in issue search with "Something"  
65 - # And I fill in issue search with ""  
66 - # Then I should see "Release 0.4" in issues  
67 - # And I should see "Release 0.3" in issues  
68 -  
69 @javascript 58 @javascript
70 Scenario: I create Issue with pre-selected milestone 59 Scenario: I create Issue with pre-selected milestone
71 Given project "Shop" has milestone "v2.2" 60 Given project "Shop" has milestone "v2.2"
features/steps/project/project_issues.rb
@@ -95,7 +95,7 @@ class ProjectIssues &lt; Spinach::FeatureSteps @@ -95,7 +95,7 @@ class ProjectIssues &lt; Spinach::FeatureSteps
95 end 95 end
96 96
97 Then 'I should see selected milestone with title "v3.0"' do 97 Then 'I should see selected milestone with title "v3.0"' do
98 - issues_milestone_selector = "#milestone_id_chzn > a" 98 + issues_milestone_selector = "#issue_milestone_id_chzn > a"
99 page.find(issues_milestone_selector).should have_content("v3.0") 99 page.find(issues_milestone_selector).should have_content("v3.0")
100 end 100 end
101 101
@@ -106,7 +106,7 @@ class ProjectIssues &lt; Spinach::FeatureSteps @@ -106,7 +106,7 @@ class ProjectIssues &lt; Spinach::FeatureSteps
106 end 106 end
107 107
108 Then 'I should see first assignee from "Shop" as selected assignee' do 108 Then 'I should see first assignee from "Shop" as selected assignee' do
109 - issues_assignee_selector = "#assignee_id_chzn > a" 109 + issues_assignee_selector = "#issue_assignee_id_chzn > a"
110 project = Project.find_by_name "Shop" 110 project = Project.find_by_name "Shop"
111 assignee_name = project.users.first.name 111 assignee_name = project.users.first.name
112 page.find(issues_assignee_selector).should have_content(assignee_name) 112 page.find(issues_assignee_selector).should have_content(assignee_name)
spec/requests/issues_spec.rb
@@ -11,7 +11,7 @@ describe &quot;Issues&quot; do @@ -11,7 +11,7 @@ describe &quot;Issues&quot; do
11 project.add_access(user2, :read, :write) 11 project.add_access(user2, :read, :write)
12 end 12 end
13 13
14 - describe "Edit issue", js: true do 14 + describe "Edit issue" do
15 let!(:issue) do 15 let!(:issue) do
16 create(:issue, 16 create(:issue,
17 author: @user, 17 author: @user,