Commit bb367689413a29eadb511f971b26363a913cb1f2

Authored by Dmitriy Zaporozhets
2 parents 248a3e56 9654b098

Merge branch 'milestone-issues-dragging' into 'master'

Milestone issues dragging

This is part of #1207.
I will submit this feature with small but finished merge requests.
app/assets/javascripts/dispatcher.js.coffee
@@ -21,6 +21,8 @@ class Dispatcher @@ -21,6 +21,8 @@ class Dispatcher
21 Issues.init() 21 Issues.init()
22 when 'projects:issues:show' 22 when 'projects:issues:show'
23 new Issue() 23 new Issue()
  24 + when 'projects:milestones:show'
  25 + new Milestone()
24 when 'projects:issues:new', 'projects:merge_requests:new' 26 when 'projects:issues:new', 'projects:merge_requests:new'
25 GitLab.GfmAutoComplete.setup() 27 GitLab.GfmAutoComplete.setup()
26 when 'dashboard:show' 28 when 'dashboard:show'
app/assets/javascripts/milestone.js.coffee 0 → 100644
@@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
  1 +class Milestone
  2 + @updateIssue: (li, issue_url, data) ->
  3 + $.ajax
  4 + type: "PUT"
  5 + url: issue_url
  6 + data: data
  7 + success: (data) ->
  8 + if data.saved == true
  9 + $(li).effect 'highlight'
  10 + else
  11 + new Flash("Issue update failed", 'alert')
  12 + dataType: "json"
  13 +
  14 + constructor: ->
  15 + @bindSorting()
  16 +
  17 + bindSorting: ->
  18 + $("#issues-list-unassigned, #issues-list-ongoing, #issues-list-closed").sortable(
  19 + connectWith: ".issues-sortable-list",
  20 + dropOnEmpty: true,
  21 + receive: (event, ui) ->
  22 + new_state = $(this).data('state')
  23 + issue_id = ui.item.data('iid')
  24 + issue_url = ui.item.data('url')
  25 +
  26 + data = switch new_state
  27 + when 'ongoing'
  28 + "issue[assignee_id]=" + gon.current_user_id
  29 + when 'unassigned'
  30 + "issue[assignee_id]="
  31 + when 'closed'
  32 + "issue[state_event]=close"
  33 +
  34 + if $(ui.sender).data('state') == "closed"
  35 + data += "&issue[state_event]=reopen"
  36 +
  37 + Milestone.updateIssue(ui.item, issue_url, data)
  38 +
  39 + ).disableSelection()
  40 +
  41 +@Milestone = Milestone
app/assets/stylesheets/main/mixins.scss
@@ -124,7 +124,7 @@ @@ -124,7 +124,7 @@
124 margin-bottom: 10px; 124 margin-bottom: 10px;
125 } 125 }
126 126
127 -@mixin str-truncated($max_width: "82%") { 127 +@mixin str-truncated($max_width: 82%) {
128 display: inline-block; 128 display: inline-block;
129 overflow: hidden; 129 overflow: hidden;
130 text-overflow: ellipsis; 130 text-overflow: ellipsis;
app/assets/stylesheets/sections/milestone.scss 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +.issues-sortable-list .str-truncated {
  2 + max-width: 70%;
  3 +}
app/controllers/application_controller.rb
@@ -174,10 +174,14 @@ class ApplicationController < ActionController::Base @@ -174,10 +174,14 @@ class ApplicationController < ActionController::Base
174 def add_gon_variables 174 def add_gon_variables
175 gon.default_issues_tracker = Project.issues_tracker.default_value 175 gon.default_issues_tracker = Project.issues_tracker.default_value
176 gon.api_version = API::API.version 176 gon.api_version = API::API.version
177 - gon.api_token = current_user.private_token if current_user  
178 gon.gravatar_url = request.ssl? || Gitlab.config.gitlab.https ? Gitlab.config.gravatar.ssl_url : Gitlab.config.gravatar.plain_url 177 gon.gravatar_url = request.ssl? || Gitlab.config.gitlab.https ? Gitlab.config.gravatar.ssl_url : Gitlab.config.gravatar.plain_url
179 gon.relative_url_root = Gitlab.config.gitlab.relative_url_root 178 gon.relative_url_root = Gitlab.config.gitlab.relative_url_root
180 gon.gravatar_enabled = Gitlab.config.gravatar.enabled 179 gon.gravatar_enabled = Gitlab.config.gravatar.enabled
  180 +
  181 + if current_user
  182 + gon.current_user_id = current_user.id
  183 + gon.api_token = current_user.private_token
  184 + end
181 end 185 end
182 186
183 def check_password_expiration 187 def check_password_expiration
app/controllers/projects/issues_controller.rb
@@ -87,6 +87,11 @@ class Projects::IssuesController < Projects::ApplicationController @@ -87,6 +87,11 @@ class Projects::IssuesController < Projects::ApplicationController
87 render :edit 87 render :edit
88 end 88 end
89 end 89 end
  90 + format.json do
  91 + render json: {
  92 + saved: @issue.valid?,
  93 + }
  94 + end
90 end 95 end
91 end 96 end
92 97
app/models/concerns/issuable.rb
@@ -24,6 +24,8 @@ module Issuable @@ -24,6 +24,8 @@ module Issuable
24 scope :unassigned, -> { where("assignee_id IS NULL") } 24 scope :unassigned, -> { where("assignee_id IS NULL") }
25 scope :of_projects, ->(ids) { where(project_id: ids) } 25 scope :of_projects, ->(ids) { where(project_id: ids) }
26 scope :opened, -> { with_state(:opened, :reopened) } 26 scope :opened, -> { with_state(:opened, :reopened) }
  27 + scope :only_opened, -> { with_state(:opened) }
  28 + scope :only_reopened, -> { with_state(:reopened) }
27 scope :closed, -> { with_state(:closed) } 29 scope :closed, -> { with_state(:closed) }
28 30
29 delegate :name, 31 delegate :name,
app/views/projects/milestones/_issue.html.haml 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +%li{ class: 'issue-row', 'data-iid' => issue.iid, 'data-url' => project_issue_path(@project, issue) }
  2 + %span.str-truncated
  3 + = link_to [@project, issue] do
  4 + %span.cgray ##{issue.iid}
  5 + = link_to_gfm issue.title, [@project, issue]
  6 + - if issue.assignee
  7 + .pull-right
  8 + = image_tag avatar_icon(issue.assignee.email, 16), class: "avatar s16"
  9 +
app/views/projects/milestones/_issues.html.haml
1 .panel.panel-default 1 .panel.panel-default
2 .panel-heading= title 2 .panel-heading= title
3 - %ul.well-list 3 + %ul{ class: "well-list issues-sortable-list", id: "issues-list-#{id}", "data-state" => id }
4 - issues.each do |issue| 4 - issues.each do |issue|
5 - %li  
6 - = link_to [@project, issue] do  
7 - %span.label{class: issue.closed? ? 'label-danger' : 'label-info'} ##{issue.iid}  
8 - = link_to_gfm truncate(issue.title, length: 40), [@project, issue]  
9 - - if issue.assignee  
10 - .pull-right  
11 - = image_tag avatar_icon(issue.assignee.email, 16), class: "avatar s16" 5 + = render 'issue', issue: issue
  6 + %li.light Drag and drop available
app/views/projects/milestones/show.html.haml
@@ -35,6 +35,12 @@ @@ -35,6 +35,12 @@
35 %h4.title 35 %h4.title
36 = gfm escape_once(@milestone.title) 36 = gfm escape_once(@milestone.title)
37 37
  38 + - if @milestone.description.present?
  39 + .description
  40 + .wiki
  41 + = preserve do
  42 + = markdown @milestone.description
  43 +
38 .context 44 .context
39 %p 45 %p
40 Progress: 46 Progress:
@@ -45,11 +51,6 @@ @@ -45,11 +51,6 @@
45 .progress.progress-info 51 .progress.progress-info
46 .progress-bar{style: "width: #{@milestone.percent_complete}%;"} 52 .progress-bar{style: "width: #{@milestone.percent_complete}%;"}
47 53
48 - - if @milestone.description.present?  
49 - .description  
50 - .wiki  
51 - = preserve do  
52 - = markdown @milestone.description  
53 54
54 %ul.nav.nav-tabs 55 %ul.nav.nav-tabs
55 %li.active 56 %li.active
@@ -75,11 +76,11 @@ @@ -75,11 +76,11 @@
75 .tab-pane.active#tab-issues 76 .tab-pane.active#tab-issues
76 .row 77 .row
77 .col-md-4 78 .col-md-4
78 - = render('issues', title: 'Unstarted Issues (open and unassigned)', issues: @issues.opened.unassigned) 79 + = render('issues', title: 'Unstarted Issues (open and unassigned)', issues: @issues.opened.unassigned, id: 'unassigned')
79 .col-md-4 80 .col-md-4
80 - = render('issues', title: 'Ongoing Issues (open and assigned)', issues: @issues.opened.assigned) 81 + = render('issues', title: 'Ongoing Issues (open and assigned)', issues: @issues.opened.assigned, id: 'ongoing')
81 .col-md-4 82 .col-md-4
82 - = render('issues', title: 'Completed Issues (closed)', issues: @issues.closed) 83 + = render('issues', title: 'Completed Issues (closed)', issues: @issues.closed, id: 'closed')
83 84
84 .tab-pane#tab-merge-requests 85 .tab-pane#tab-merge-requests
85 .row 86 .row
features/steps/project/milestones.rb
@@ -54,6 +54,6 @@ class ProjectMilestones < Spinach::FeatureSteps @@ -54,6 +54,6 @@ class ProjectMilestones < Spinach::FeatureSteps
54 end 54 end
55 55
56 Then "I should see 3 issues" do 56 Then "I should see 3 issues" do
57 - page.should have_selector('#tab-issues li', count: 4) 57 + page.should have_selector('#tab-issues li.issue-row', count: 4)
58 end 58 end
59 end 59 end