Merge branch 'close-open-ajax-issue' into 'master'
open and close issue via ajax request. With tests Close and Reopen issues with ajax request. See merge request !2164
This commit is contained in:
commit
98f77d2edc
5 changed files with 138 additions and 11 deletions
|
@ -1,3 +1,4 @@
|
|||
#= require flash
|
||||
#= require jquery.waitforimages
|
||||
#= require task_list
|
||||
|
||||
|
@ -6,13 +7,44 @@ class @Issue
|
|||
# Prevent duplicate event bindings
|
||||
@disableTaskList()
|
||||
|
||||
if $("a.btn-close").length
|
||||
if $('a.btn-close').length
|
||||
@initTaskList()
|
||||
@initIssueBtnEventListeners()
|
||||
|
||||
initTaskList: ->
|
||||
$('.detail-page-description .js-task-list-container').taskList('enable')
|
||||
$(document).on 'tasklist:changed', '.detail-page-description .js-task-list-container', @updateTaskList
|
||||
|
||||
initIssueBtnEventListeners: ->
|
||||
issueFailMessage = 'Unable to update this issue at this time.'
|
||||
$('a.btn-close, a.btn-reopen').on 'click', (e) ->
|
||||
e.preventDefault()
|
||||
e.stopImmediatePropagation()
|
||||
$this = $(this)
|
||||
isClose = $this.hasClass('btn-close')
|
||||
$this.prop('disabled', true)
|
||||
url = $this.attr('href')
|
||||
$.ajax
|
||||
type: 'PUT'
|
||||
url: url,
|
||||
error: (jqXHR, textStatus, errorThrown) ->
|
||||
issueStatus = if isClose then 'close' else 'open'
|
||||
new Flash(issueFailMessage, 'alert')
|
||||
success: (data, textStatus, jqXHR) ->
|
||||
if data.saved
|
||||
$this.addClass('hidden')
|
||||
if isClose
|
||||
$('a.btn-reopen').removeClass('hidden')
|
||||
$('div.status-box-closed').removeClass('hidden')
|
||||
$('div.status-box-open').addClass('hidden')
|
||||
else
|
||||
$('a.btn-close').removeClass('hidden')
|
||||
$('div.status-box-closed').addClass('hidden')
|
||||
$('div.status-box-open').removeClass('hidden')
|
||||
else
|
||||
new Flash(issueFailMessage, 'alert')
|
||||
$this.prop('disabled', false)
|
||||
|
||||
disableTaskList: ->
|
||||
$('.detail-page-description .js-task-list-container').taskList('disable')
|
||||
$(document).off 'tasklist:changed', '.detail-page-description .js-task-list-container'
|
||||
|
|
|
@ -69,6 +69,10 @@ module IssuesHelper
|
|||
end
|
||||
end
|
||||
|
||||
def issue_button_visibility(issue, closed)
|
||||
return 'hidden' if issue.closed? == closed
|
||||
end
|
||||
|
||||
def issue_to_atom(xml, issue)
|
||||
xml.entry do
|
||||
xml.id namespace_project_issue_url(issue.project.namespace,
|
||||
|
|
|
@ -6,11 +6,8 @@
|
|||
|
||||
.issue
|
||||
.detail-page-header
|
||||
.status-box{ class: status_box_class(@issue) }
|
||||
- if @issue.closed?
|
||||
Closed
|
||||
- else
|
||||
Open
|
||||
.status-box{ class: "status-box-closed #{issue_button_visibility(@issue, false)}"} Closed
|
||||
.status-box{ class: "status-box-open #{issue_button_visibility(@issue, true)}"} Open
|
||||
%span.identifier
|
||||
Issue ##{@issue.iid}
|
||||
%span.creator
|
||||
|
@ -30,10 +27,8 @@
|
|||
= icon('plus')
|
||||
New Issue
|
||||
- if can?(current_user, :update_issue, @issue)
|
||||
- if @issue.closed?
|
||||
= link_to 'Reopen', issue_path(@issue, issue: {state_event: :reopen}, status_only: true), method: :put, class: 'btn btn-nr btn-grouped btn-reopen'
|
||||
- else
|
||||
= link_to 'Close', issue_path(@issue, issue: {state_event: :close}, status_only: true), method: :put, class: 'btn btn-nr btn-grouped btn-close', title: 'Close Issue'
|
||||
= link_to 'Reopen', issue_path(@issue, issue: {state_event: :reopen}, status_only: true, format: 'json'), data: {no_turbolink: true}, class: "btn btn-nr btn-grouped btn-reopen #{issue_button_visibility(@issue, false)}", title: 'Reopen Issue'
|
||||
= link_to 'Close', issue_path(@issue, issue: {state_event: :close}, status_only: true, format: 'json'), data: {no_turbolink: true}, class: "btn btn-nr btn-grouped btn-close #{issue_button_visibility(@issue, true)}", title: 'Close Issue'
|
||||
|
||||
= link_to edit_namespace_project_issue_path(@project.namespace, @project, @issue), class: 'btn btn-nr btn-grouped issuable-edit' do
|
||||
= icon('pencil-square-o')
|
||||
|
|
|
@ -1,4 +1,14 @@
|
|||
%a.btn-close
|
||||
:css
|
||||
.hidden { display: none !important; }
|
||||
|
||||
.flash-container
|
||||
.flash-alert
|
||||
.flash-notice
|
||||
|
||||
.status-box.status-box-open Open
|
||||
.status-box.status-box-closed.hidden Closed
|
||||
%a.btn-close{"href" => "http://gitlab.com/issues/6/close"} Close
|
||||
%a.btn-reopen.hidden{"href" => "http://gitlab.com/issues/6/reopen"} Reopen
|
||||
|
||||
.detail-page-description
|
||||
.description.js-task-list-container
|
||||
|
|
|
@ -20,3 +20,89 @@ describe 'Issue', ->
|
|||
expect(req.data.issue.description).not.toBe(null)
|
||||
|
||||
$('.js-task-list-field').trigger('tasklist:changed')
|
||||
describe 'reopen/close issue', ->
|
||||
fixture.preload('issues_show.html')
|
||||
beforeEach ->
|
||||
fixture.load('issues_show.html')
|
||||
@issue = new Issue()
|
||||
it 'closes an issue', ->
|
||||
$.ajax = (obj) ->
|
||||
expect(obj.type).toBe('PUT')
|
||||
expect(obj.url).toBe('http://gitlab.com/issues/6/close')
|
||||
obj.success saved: true
|
||||
|
||||
$btnClose = $('a.btn-close')
|
||||
$btnReopen = $('a.btn-reopen')
|
||||
expect($btnReopen).toBeHidden()
|
||||
expect($btnClose.text()).toBe('Close')
|
||||
expect(typeof $btnClose.prop('disabled')).toBe('undefined')
|
||||
|
||||
$btnClose.trigger('click')
|
||||
|
||||
expect($btnReopen).toBeVisible()
|
||||
expect($btnClose).toBeHidden()
|
||||
expect($('div.status-box-closed')).toBeVisible()
|
||||
expect($('div.status-box-open')).toBeHidden()
|
||||
|
||||
it 'fails to closes an issue with success:false', ->
|
||||
|
||||
$.ajax = (obj) ->
|
||||
expect(obj.type).toBe('PUT')
|
||||
expect(obj.url).toBe('http://goesnowhere.nothing/whereami')
|
||||
obj.success saved: false
|
||||
|
||||
$btnClose = $('a.btn-close')
|
||||
$btnReopen = $('a.btn-reopen')
|
||||
$btnClose.attr('href','http://goesnowhere.nothing/whereami')
|
||||
expect($btnReopen).toBeHidden()
|
||||
expect($btnClose.text()).toBe('Close')
|
||||
expect(typeof $btnClose.prop('disabled')).toBe('undefined')
|
||||
|
||||
$btnClose.trigger('click')
|
||||
|
||||
expect($btnReopen).toBeHidden()
|
||||
expect($btnClose).toBeVisible()
|
||||
expect($('div.status-box-closed')).toBeHidden()
|
||||
expect($('div.status-box-open')).toBeVisible()
|
||||
expect($('div.flash-alert')).toBeVisible()
|
||||
expect($('div.flash-alert').text()).toBe('Unable to update this issue at this time.')
|
||||
|
||||
it 'fails to closes an issue with HTTP error', ->
|
||||
|
||||
$.ajax = (obj) ->
|
||||
expect(obj.type).toBe('PUT')
|
||||
expect(obj.url).toBe('http://goesnowhere.nothing/whereami')
|
||||
obj.error()
|
||||
|
||||
$btnClose = $('a.btn-close')
|
||||
$btnReopen = $('a.btn-reopen')
|
||||
$btnClose.attr('href','http://goesnowhere.nothing/whereami')
|
||||
expect($btnReopen).toBeHidden()
|
||||
expect($btnClose.text()).toBe('Close')
|
||||
expect(typeof $btnClose.prop('disabled')).toBe('undefined')
|
||||
|
||||
$btnClose.trigger('click')
|
||||
|
||||
expect($btnReopen).toBeHidden()
|
||||
expect($btnClose).toBeVisible()
|
||||
expect($('div.status-box-closed')).toBeHidden()
|
||||
expect($('div.status-box-open')).toBeVisible()
|
||||
expect($('div.flash-alert')).toBeVisible()
|
||||
expect($('div.flash-alert').text()).toBe('Unable to update this issue at this time.')
|
||||
|
||||
it 'reopens an issue', ->
|
||||
$.ajax = (obj) ->
|
||||
expect(obj.type).toBe('PUT')
|
||||
expect(obj.url).toBe('http://gitlab.com/issues/6/reopen')
|
||||
obj.success saved: true
|
||||
|
||||
$btnClose = $('a.btn-close')
|
||||
$btnReopen = $('a.btn-reopen')
|
||||
expect($btnReopen.text()).toBe('Reopen')
|
||||
|
||||
$btnReopen.trigger('click')
|
||||
|
||||
expect($btnReopen).toBeHidden()
|
||||
expect($btnClose).toBeVisible()
|
||||
expect($('div.status-box-open')).toBeVisible()
|
||||
expect($('div.status-box-closed')).toBeHidden()
|
Loading…
Reference in a new issue