BigW Consortium Gitlab
Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
gitlab-ce
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Forest Godfrey
gitlab-ce
Commits
83c9d8cf
Commit
83c9d8cf
authored
Apr 12, 2017
by
💃 Winnie 💃
Committed by
Alfredo Sumaran
Apr 12, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reset New branch button when issue state changes
parent
defdf45a
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
170 additions
and
136 deletions
+170
-136
issue.js
app/assets/javascripts/issue.js
+57
-51
reset-new-branch-button.yml
changelogs/unreleased/reset-new-branch-button.yml
+4
-0
issue_spec.js
spec/javascripts/issue_spec.js
+109
-85
No files found.
app/assets/javascripts/issue.js
View file @
83c9d8cf
...
...
@@ -20,57 +20,60 @@ class Issue {
});
Issue
.
initIssueBtnEventListeners
();
}
Issue
.
$btnNewBranch
=
$
(
'#new-branch'
);
Issue
.
initMergeRequests
();
Issue
.
initRelatedBranches
();
Issue
.
initCanCreateBranch
();
}
static
initIssueBtnEventListeners
()
{
var
issueFailMessage
;
issueFailMessage
=
'Unable to update this issue at this time.'
;
return
$
(
'a.btn-close, a.btn-reopen'
).
on
(
'click'
,
function
(
e
)
{
var
$this
,
isClose
,
shouldSubmit
,
url
;
const
issueFailMessage
=
'Unable to update this issue at this time.'
;
const
closeButtons
=
$
(
'a.btn-close'
);
const
isClosedBadge
=
$
(
'div.status-box-closed'
);
const
isOpenBadge
=
$
(
'div.status-box-open'
);
const
projectIssuesCounter
=
$
(
'.issue_counter'
);
const
reopenButtons
=
$
(
'a.btn-reopen'
);
return
closeButtons
.
add
(
reopenButtons
).
on
(
'click'
,
function
(
e
)
{
var
$this
,
shouldSubmit
,
url
;
e
.
preventDefault
();
e
.
stopImmediatePropagation
();
$this
=
$
(
this
);
isClose
=
$this
.
hasClass
(
'btn-close'
);
shouldSubmit
=
$this
.
hasClass
(
'btn-comment'
);
if
(
shouldSubmit
)
{
Issue
.
submitNoteForm
(
$this
.
closest
(
'form'
));
}
$this
.
prop
(
'disabled'
,
true
);
Issue
.
setNewBranchButtonState
(
true
,
null
);
url
=
$this
.
attr
(
'href'
);
return
$
.
ajax
({
type
:
'PUT'
,
url
:
url
,
error
:
function
(
jqXHR
,
textStatus
,
errorThrown
)
{
var
issueStatus
;
issueStatus
=
isClose
?
'close'
:
'open'
;
return
new
Flash
(
issueFailMessage
,
'alert'
);
},
success
:
function
(
data
,
textStatus
,
jqXHR
)
{
if
(
'id'
in
data
)
{
$
(
document
).
trigger
(
'issuable:change'
);
let
total
=
Number
(
$
(
'.issue_counter'
).
text
().
replace
(
/
[^\d]
/
,
''
));
if
(
isClose
)
{
$
(
'a.btn-close'
).
addClass
(
'hidden'
);
$
(
'a.btn-reopen'
).
removeClass
(
'hidden'
);
$
(
'div.status-box-closed'
).
removeClass
(
'hidden'
);
$
(
'div.status-box-open'
).
addClass
(
'hidden'
);
total
-=
1
;
}
else
{
$
(
'a.btn-reopen'
).
addClass
(
'hidden'
);
$
(
'a.btn-close'
).
removeClass
(
'hidden'
);
$
(
'div.status-box-closed'
).
addClass
(
'hidden'
);
$
(
'div.status-box-open'
).
removeClass
(
'hidden'
);
total
+=
1
;
}
$
(
'.issue_counter'
).
text
(
gl
.
text
.
addDelimiter
(
total
));
}
else
{
new
Flash
(
issueFailMessage
,
'alert'
);
}
return
$this
.
prop
(
'disabled'
,
false
);
url
:
url
}).
fail
(
function
(
jqXHR
,
textStatus
,
errorThrown
)
{
new
Flash
(
issueFailMessage
);
Issue
.
initCanCreateBranch
();
}).
done
(
function
(
data
,
textStatus
,
jqXHR
)
{
if
(
'id'
in
data
)
{
$
(
document
).
trigger
(
'issuable:change'
);
const
isClosed
=
$this
.
hasClass
(
'btn-close'
);
closeButtons
.
toggleClass
(
'hidden'
,
isClosed
);
reopenButtons
.
toggleClass
(
'hidden'
,
!
isClosed
);
isClosedBadge
.
toggleClass
(
'hidden'
,
!
isClosed
);
isOpenBadge
.
toggleClass
(
'hidden'
,
isClosed
);
let
numProjectIssues
=
Number
(
projectIssuesCounter
.
text
().
replace
(
/
[^\d]
/
,
''
));
numProjectIssues
=
isClosed
?
numProjectIssues
-
1
:
numProjectIssues
+
1
;
projectIssuesCounter
.
text
(
gl
.
text
.
addDelimiter
(
numProjectIssues
));
}
else
{
new
Flash
(
issueFailMessage
);
}
$this
.
prop
(
'disabled'
,
false
);
Issue
.
initCanCreateBranch
();
});
});
}
...
...
@@ -86,9 +89,9 @@ class Issue {
static
initMergeRequests
()
{
var
$container
;
$container
=
$
(
'#merge-requests'
);
return
$
.
getJSON
(
$container
.
data
(
'url'
)).
error
(
function
()
{
return
new
Flash
(
'Failed to load referenced merge requests'
,
'alert'
);
}).
success
(
function
(
data
)
{
return
$
.
getJSON
(
$container
.
data
(
'url'
)).
fail
(
function
()
{
return
new
Flash
(
'Failed to load referenced merge requests'
);
}).
done
(
function
(
data
)
{
if
(
'html'
in
data
)
{
return
$container
.
html
(
data
.
html
);
}
...
...
@@ -98,9 +101,9 @@ class Issue {
static
initRelatedBranches
()
{
var
$container
;
$container
=
$
(
'#related-branches'
);
return
$
.
getJSON
(
$container
.
data
(
'url'
)).
error
(
function
()
{
return
new
Flash
(
'Failed to load related branches'
,
'alert'
);
}).
success
(
function
(
data
)
{
return
$
.
getJSON
(
$container
.
data
(
'url'
)).
fail
(
function
()
{
return
new
Flash
(
'Failed to load related branches'
);
}).
done
(
function
(
data
)
{
if
(
'html'
in
data
)
{
return
$container
.
html
(
data
.
html
);
}
...
...
@@ -108,24 +111,27 @@ class Issue {
}
static
initCanCreateBranch
()
{
var
$container
;
$container
=
$
(
'#new-branch'
);
// If the user doesn't have the required permissions the container isn't
// rendered at all.
if
(
$container
.
length
===
0
)
{
if
(
Issue
.
$btnNewBranch
.
length
===
0
)
{
return
;
}
return
$
.
getJSON
(
$container
.
data
(
'path'
)).
error
(
function
()
{
$container
.
find
(
'.unavailable'
).
show
();
return
new
Flash
(
'Failed to check if a new branch can be created.'
,
'alert'
);
}).
success
(
function
(
data
)
{
if
(
data
.
can_create_branch
)
{
$container
.
find
(
'.available'
).
show
();
}
else
{
return
$container
.
find
(
'.unavailable'
).
show
();
}
return
$
.
getJSON
(
Issue
.
$btnNewBranch
.
data
(
'path'
)).
fail
(
function
()
{
Issue
.
setNewBranchButtonState
(
false
,
false
);
new
Flash
(
'Failed to check if a new branch can be created.'
);
}).
done
(
function
(
data
)
{
Issue
.
setNewBranchButtonState
(
false
,
data
.
can_create_branch
);
});
}
static
setNewBranchButtonState
(
isPending
,
canCreate
)
{
if
(
Issue
.
$btnNewBranch
.
length
===
0
)
{
return
;
}
Issue
.
$btnNewBranch
.
find
(
'.available'
).
toggle
(
!
isPending
&&
canCreate
);
Issue
.
$btnNewBranch
.
find
(
'.unavailable'
).
toggle
(
!
isPending
&&
!
canCreate
);
}
}
export
default
Issue
;
changelogs/unreleased/reset-new-branch-button.yml
0 → 100644
View file @
83c9d8cf
---
title
:
Reset New branch button when issue state changes
merge_request
:
5962
author
:
winniehell
spec/javascripts/issue_spec.js
View file @
83c9d8cf
/* eslint-disable space-before-function-paren,
no-var,
one-var, one-var-declaration-per-line, no-use-before-define, comma-dangle, max-len */
/* eslint-disable space-before-function-paren, one-var, one-var-declaration-per-line, no-use-before-define, comma-dangle, max-len */
import
Issue
from
'~/issue'
;
require
(
'~/lib/utils/text_utility'
);
describe
(
'Issue'
,
function
()
{
var
INVALID_URL
=
'http://goesnowhere.nothing/whereami'
;
var
$boxClosed
,
$boxOpen
,
$btnClose
,
$btnReopen
;
let
$boxClosed
,
$boxOpen
,
$btnClose
,
$btnReopen
;
preloadFixtures
(
'issues/closed-issue.html.raw'
);
preloadFixtures
(
'issues/issue-with-task-list.html.raw'
);
preloadFixtures
(
'issues/open-issue.html.raw'
);
function
expectErrorMessage
()
{
var
$flashMessage
=
$
(
'div.flash-alert'
);
const
$flashMessage
=
$
(
'div.flash-alert'
);
expect
(
$flashMessage
).
toExist
();
expect
(
$flashMessage
).
toBeVisible
();
expect
(
$flashMessage
).
toHaveText
(
'Unable to update this issue at this time.'
);
...
...
@@ -26,10 +25,28 @@ describe('Issue', function() {
expectVisibility
(
$btnReopen
,
!
isIssueOpen
);
}
function
expectPendingRequest
(
req
,
$triggeredButton
)
{
expect
(
req
.
type
).
toBe
(
'PUT'
);
expect
(
req
.
url
).
toBe
(
$triggeredButton
.
attr
(
'href'
));
expect
(
$triggeredButton
).
toHaveProp
(
'disabled'
,
true
);
function
expectNewBranchButtonState
(
isPending
,
canCreate
)
{
if
(
Issue
.
$btnNewBranch
.
length
===
0
)
{
return
;
}
const
$available
=
Issue
.
$btnNewBranch
.
find
(
'.available'
);
expect
(
$available
).
toHaveText
(
'New branch'
);
if
(
!
isPending
&&
canCreate
)
{
expect
(
$available
).
toBeVisible
();
}
else
{
expect
(
$available
).
toBeHidden
();
}
const
$unavailable
=
Issue
.
$btnNewBranch
.
find
(
'.unavailable'
);
expect
(
$unavailable
).
toHaveText
(
'New branch unavailable'
);
if
(
!
isPending
&&
!
canCreate
)
{
expect
(
$unavailable
).
toBeVisible
();
}
else
{
expect
(
$unavailable
).
toBeHidden
();
}
}
function
expectVisibility
(
$element
,
shouldBeVisible
)
{
...
...
@@ -81,100 +98,107 @@ describe('Issue', function() {
});
});
describe
(
'close issue'
,
function
()
{
beforeEach
(
function
()
{
loadFixtures
(
'issues/open-issue.html.raw'
);
findElements
();
this
.
issue
=
new
Issue
();
expectIssueState
(
true
);
});
[
true
,
false
].
forEach
((
isIssueInitiallyOpen
)
=>
{
describe
(
`with
${
isIssueInitiallyOpen
?
'open'
:
'closed'
}
issue`
,
function
()
{
const
action
=
isIssueInitiallyOpen
?
'close'
:
'reopen'
;
function
ajaxSpy
(
req
)
{
if
(
req
.
url
===
this
.
$triggeredButton
.
attr
(
'href'
))
{
expect
(
req
.
type
).
toBe
(
'PUT'
);
expect
(
this
.
$triggeredButton
).
toHaveProp
(
'disabled'
,
true
);
expectNewBranchButtonState
(
true
,
false
);
return
this
.
issueStateDeferred
;
}
else
if
(
req
.
url
===
Issue
.
$btnNewBranch
.
data
(
'path'
))
{
expect
(
req
.
type
).
toBe
(
'get'
);
expectNewBranchButtonState
(
true
,
false
);
return
this
.
canCreateBranchDeferred
;
}
expect
(
req
.
url
).
toBe
(
'unexpected'
);
return
null
;
}
beforeEach
(
function
()
{
if
(
isIssueInitiallyOpen
)
{
loadFixtures
(
'issues/open-issue.html.raw'
);
}
else
{
loadFixtures
(
'issues/closed-issue.html.raw'
);
}
findElements
();
this
.
issue
=
new
Issue
();
expectIssueState
(
isIssueInitiallyOpen
);
this
.
$triggeredButton
=
isIssueInitiallyOpen
?
$btnClose
:
$btnReopen
;
this
.
$projectIssuesCounter
=
$
(
'.issue_counter'
);
this
.
$projectIssuesCounter
.
text
(
'1,001'
);
this
.
issueStateDeferred
=
new
jQuery
.
Deferred
();
this
.
canCreateBranchDeferred
=
new
jQuery
.
Deferred
();
spyOn
(
jQuery
,
'ajax'
).
and
.
callFake
(
ajaxSpy
.
bind
(
this
));
});
it
(
'closes an issue'
,
function
()
{
spyOn
(
jQuery
,
'ajax'
).
and
.
callFake
(
function
(
req
)
{
expectPendingRequest
(
req
,
$btnClose
);
req
.
success
({
it
(
`
${
action
}
s the issue`
,
function
()
{
this
.
$triggeredButton
.
trigger
(
'click'
);
this
.
issueStateDeferred
.
resolve
({
id
:
34
});
});
$btnClose
.
trigger
(
'click'
);
this
.
canCreateBranchDeferred
.
resolve
({
can_create_branch
:
!
isIssueInitiallyOpen
}
);
expectIssueState
(
false
);
expect
(
$btnClose
).
toHaveProp
(
'disabled'
,
false
);
expect
(
$
(
'.issue_counter'
)).
toHaveText
(
0
);
});
expectIssueState
(
!
isIssueInitiallyOpen
);
expect
(
this
.
$triggeredButton
).
toHaveProp
(
'disabled'
,
false
);
expect
(
this
.
$projectIssuesCounter
.
text
()).
toBe
(
isIssueInitiallyOpen
?
'1,000'
:
'1,002'
);
expectNewBranchButtonState
(
false
,
!
isIssueInitiallyOpen
);
});
it
(
'fails to close an issue with success:false'
,
function
()
{
spyOn
(
jQuery
,
'ajax'
).
and
.
callFake
(
function
(
req
)
{
expectPendingRequest
(
req
,
$btnClose
);
req
.
success
({
it
(
`fails to
${
action
}
the issue if saved:false`
,
function
()
{
this
.
$triggeredButton
.
trigger
(
'click'
);
this
.
issueStateDeferred
.
resolve
({
saved
:
false
});
});
$btnClose
.
attr
(
'href'
,
INVALID_URL
);
$btnClose
.
trigger
(
'click'
);
expectIssueState
(
true
);
expect
(
$btnClose
).
toHaveProp
(
'disabled'
,
false
);
expectErrorMessage
();
expect
(
$
(
'.issue_counter'
)).
toHaveText
(
1
);
});
this
.
canCreateBranchDeferred
.
resolve
({
can_create_branch
:
isIssueInitiallyOpen
});
it
(
'fails to closes an issue with HTTP error'
,
function
()
{
spyOn
(
jQuery
,
'ajax'
).
and
.
callFake
(
function
(
req
)
{
expectPendingRequest
(
req
,
$btnClose
);
req
.
error
();
expectIssueState
(
isIssueInitiallyOpen
);
expect
(
this
.
$triggeredButton
).
toHaveProp
(
'disabled'
,
false
);
expectErrorMessage
();
expect
(
this
.
$projectIssuesCounter
.
text
()).
toBe
(
'1,001'
);
expectNewBranchButtonState
(
false
,
isIssueInitiallyOpen
);
});
$btnClose
.
attr
(
'href'
,
INVALID_URL
);
$btnClose
.
trigger
(
'click'
);
expectIssueState
(
true
);
expect
(
$btnClose
).
toHaveProp
(
'disabled'
,
true
);
expectErrorMessage
();
expect
(
$
(
'.issue_counter'
)).
toHaveText
(
1
);
});
it
(
'updates counter'
,
()
=>
{
spyOn
(
jQuery
,
'ajax'
).
and
.
callFake
(
function
(
req
)
{
expectPendingRequest
(
req
,
$btnClose
);
req
.
success
({
id
:
34
it
(
`fails to
${
action
}
the issue if HTTP error occurs`
,
function
()
{
this
.
$triggeredButton
.
trigger
(
'click'
);
this
.
issueStateDeferred
.
reject
();
this
.
canCreateBranchDeferred
.
resolve
({
can_create_branch
:
isIssueInitiallyOpen
});
});
expect
(
$
(
'.issue_counter'
)).
toHaveText
(
1
);
$
(
'.issue_counter'
).
text
(
'1,001'
);
expect
(
$
(
'.issue_counter'
).
text
()).
toEqual
(
'1,001'
);
$btnClose
.
trigger
(
'click'
);
expect
(
$
(
'.issue_counter'
).
text
()).
toEqual
(
'1,000'
);
});
});
expectIssueState
(
isIssueInitiallyOpen
);
expect
(
this
.
$triggeredButton
).
toHaveProp
(
'disabled'
,
true
);
expectErrorMessage
();
expect
(
this
.
$projectIssuesCounter
.
text
()).
toBe
(
'1,001'
);
expectNewBranchButtonState
(
false
,
isIssueInitiallyOpen
);
});
describe
(
'reopen issue'
,
function
()
{
beforeEach
(
function
()
{
loadFixtures
(
'issues/closed-issue.html.raw'
);
findElements
();
this
.
issue
=
new
Issue
();
it
(
'disables the new branch button if Ajax call fails'
,
function
()
{
this
.
$triggeredButton
.
trigger
(
'click'
);
this
.
issueStateDeferred
.
reject
();
this
.
canCreateBranchDeferred
.
reject
();
expectIssueState
(
false
);
});
it
(
'reopens an issue'
,
function
()
{
spyOn
(
jQuery
,
'ajax'
).
and
.
callFake
(
function
(
req
)
{
expectPendingRequest
(
req
,
$btnReopen
);
req
.
success
({
id
:
34
});
expectNewBranchButtonState
(
false
,
false
);
});
$btnReopen
.
trigger
(
'click'
);
it
(
'does not trigger Ajax call if new branch button is missing'
,
function
()
{
Issue
.
$btnNewBranch
=
$
();
this
.
canCreateBranchDeferred
=
null
;
expectIssueState
(
true
);
expect
(
$btnReopen
).
toHaveProp
(
'disabled'
,
false
);
expect
(
$
(
'.issue_counter'
)).
toHaveText
(
1
);
this
.
$triggeredButton
.
trigger
(
'click'
);
this
.
issueStateDeferred
.
reject
(
);
}
);
});
});
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment