Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
c559bcca
Commit
c559bcca
authored
Oct 10, 2018
by
Mike Greiling
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Prettify additional modules (I through Z)
parent
aeaf6686
Changes
50
Show whitespace changes
Inline
Side-by-side
Showing
50 changed files
with
1330 additions
and
1051 deletions
+1330
-1051
app/assets/javascripts/issuable_index.js
app/assets/javascripts/issuable_index.js
+6
-3
app/assets/javascripts/issue.js
app/assets/javascripts/issue.js
+44
-29
app/assets/javascripts/job.js
app/assets/javascripts/job.js
+13
-15
app/assets/javascripts/label_manager.js
app/assets/javascripts/label_manager.js
+7
-7
app/assets/javascripts/labels.js
app/assets/javascripts/labels.js
+1
-1
app/assets/javascripts/layout_nav.js
app/assets/javascripts/layout_nav.js
+33
-27
app/assets/javascripts/line_highlighter.js
app/assets/javascripts/line_highlighter.js
+17
-11
app/assets/javascripts/locale/sprintf.js
app/assets/javascripts/locale/sprintf.js
+1
-1
app/assets/javascripts/member_expiration_date.js
app/assets/javascripts/member_expiration_date.js
+6
-2
app/assets/javascripts/merge_request.js
app/assets/javascripts/merge_request.js
+13
-10
app/assets/javascripts/milestone.js
app/assets/javascripts/milestone.js
+20
-14
app/assets/javascripts/mini_pipeline_graph_dropdown.js
app/assets/javascripts/mini_pipeline_graph_dropdown.js
+11
-6
app/assets/javascripts/namespace_select.js
app/assets/javascripts/namespace_select.js
+4
-4
app/assets/javascripts/network/branch_graph.js
app/assets/javascripts/network/branch_graph.js
+89
-73
app/assets/javascripts/network/raphael.js
app/assets/javascripts/network/raphael.js
+1
-1
app/assets/javascripts/new_branch_form.js
app/assets/javascripts/new_branch_form.js
+7
-7
app/assets/javascripts/new_commit_form.js
app/assets/javascripts/new_commit_form.js
+1
-3
app/assets/javascripts/notifications_dropdown.js
app/assets/javascripts/notifications_dropdown.js
+3
-1
app/assets/javascripts/notifications_form.js
app/assets/javascripts/notifications_form.js
+7
-3
app/assets/javascripts/pager.js
app/assets/javascripts/pager.js
+18
-15
app/assets/javascripts/pdf/index.vue
app/assets/javascripts/pdf/index.vue
+52
-51
app/assets/javascripts/pdf/page/index.vue
app/assets/javascripts/pdf/page/index.vue
+53
-50
app/assets/javascripts/pipelines/components/pipelines_table_row.vue
.../javascripts/pipelines/components/pipelines_table_row.vue
+1
-4
app/assets/javascripts/project_find_file.js
app/assets/javascripts/project_find_file.js
+56
-39
app/assets/javascripts/project_import.js
app/assets/javascripts/project_import.js
+0
-1
app/assets/javascripts/project_label_subscription.js
app/assets/javascripts/project_label_subscription.js
+23
-20
app/assets/javascripts/project_select.js
app/assets/javascripts/project_select.js
+29
-20
app/assets/javascripts/project_select_combo_button.js
app/assets/javascripts/project_select_combo_button.js
+20
-7
app/assets/javascripts/project_visibility.js
app/assets/javascripts/project_visibility.js
+2
-3
app/assets/javascripts/prometheus_metrics/prometheus_metrics.js
...sets/javascripts/prometheus_metrics/prometheus_metrics.js
+25
-11
app/assets/javascripts/raven/raven_config.js
app/assets/javascripts/raven/raven_config.js
+1
-1
app/assets/javascripts/ref_select_dropdown.js
app/assets/javascripts/ref_select_dropdown.js
+3
-2
app/assets/javascripts/settings_panels.js
app/assets/javascripts/settings_panels.js
+8
-3
app/assets/javascripts/single_file_diff.js
app/assets/javascripts/single_file_diff.js
+25
-9
app/assets/javascripts/smart_interval.js
app/assets/javascripts/smart_interval.js
+12
-8
app/assets/javascripts/star.js
app/assets/javascripts/star.js
+6
-2
app/assets/javascripts/task_list.js
app/assets/javascripts/task_list.js
+7
-2
app/assets/javascripts/templates/issuable_template_selector.js
...ssets/javascripts/templates/issuable_template_selector.js
+12
-6
app/assets/javascripts/terminal/terminal.js
app/assets/javascripts/terminal/terminal.js
+8
-4
app/assets/javascripts/test_utils/simulate_drag.js
app/assets/javascripts/test_utils/simulate_drag.js
+43
-13
app/assets/javascripts/test_utils/simulate_input.js
app/assets/javascripts/test_utils/simulate_input.js
+1
-1
app/assets/javascripts/toggle_buttons.js
app/assets/javascripts/toggle_buttons.js
+1
-1
app/assets/javascripts/tree.js
app/assets/javascripts/tree.js
+9
-9
app/assets/javascripts/u2f/authenticate.js
app/assets/javascripts/u2f/authenticate.js
+9
-5
app/assets/javascripts/u2f/register.js
app/assets/javascripts/u2f/register.js
+9
-4
app/assets/javascripts/u2f/util.js
app/assets/javascripts/u2f/util.js
+2
-3
app/assets/javascripts/ui_development_kit.js
app/assets/javascripts/ui_development_kit.js
+11
-7
app/assets/javascripts/usage_ping_consent.js
app/assets/javascripts/usage_ping_consent.js
+3
-2
app/assets/javascripts/users_select.js
app/assets/javascripts/users_select.js
+576
-519
app/assets/javascripts/zen_mode.js
app/assets/javascripts/zen_mode.js
+21
-11
No files found.
app/assets/javascripts/issuable_index.js
View file @
c559bcca
...
...
@@ -26,14 +26,17 @@ export default class IssuableIndex {
static
resetIncomingEmailToken
()
{
const
$resetToken
=
$
(
'
.incoming-email-token-reset
'
);
$resetToken
.
on
(
'
click
'
,
(
e
)
=>
{
$resetToken
.
on
(
'
click
'
,
e
=>
{
e
.
preventDefault
();
$resetToken
.
text
(
'
resetting...
'
);
axios
.
put
(
$resetToken
.
attr
(
'
href
'
))
axios
.
put
(
$resetToken
.
attr
(
'
href
'
))
.
then
(({
data
})
=>
{
$
(
'
#issuable_email
'
).
val
(
data
.
new_address
).
focus
();
$
(
'
#issuable_email
'
)
.
val
(
data
.
new_address
)
.
focus
();
$resetToken
.
text
(
'
reset it
'
);
})
...
...
app/assets/javascripts/issue.js
View file @
c559bcca
...
...
@@ -28,7 +28,7 @@ export default class Issue {
}
// Listen to state changes in the Vue app
document
.
addEventListener
(
'
issuable_vue_app:change
'
,
(
event
)
=>
{
document
.
addEventListener
(
'
issuable_vue_app:change
'
,
event
=>
{
this
.
updateTopState
(
event
.
detail
.
isClosed
,
event
.
detail
.
data
);
});
}
...
...
@@ -55,7 +55,13 @@ export default class Issue {
$
(
document
).
trigger
(
'
issuable:change
'
,
isClosed
);
this
.
toggleCloseReopenButton
(
isClosed
);
let
numProjectIssues
=
Number
(
projectIssuesCounter
.
first
().
text
().
trim
().
replace
(
/
[^\d]
/
,
''
));
let
numProjectIssues
=
Number
(
projectIssuesCounter
.
first
()
.
text
()
.
trim
()
.
replace
(
/
[^\d]
/
,
''
),
);
numProjectIssues
=
isClosed
?
numProjectIssues
-
1
:
numProjectIssues
+
1
;
projectIssuesCounter
.
text
(
addDelimiter
(
numProjectIssues
));
...
...
@@ -76,7 +82,10 @@ export default class Issue {
initIssueBtnEventListeners
()
{
const
issueFailMessage
=
'
Unable to update this issue at this time.
'
;
return
$
(
document
).
on
(
'
click
'
,
'
.js-issuable-actions a.btn-close, .js-issuable-actions a.btn-reopen
'
,
(
e
)
=>
{
return
$
(
document
).
on
(
'
click
'
,
'
.js-issuable-actions a.btn-close, .js-issuable-actions a.btn-reopen
'
,
e
=>
{
var
$button
,
shouldSubmit
,
url
;
e
.
preventDefault
();
e
.
stopImmediatePropagation
();
...
...
@@ -89,7 +98,8 @@ export default class Issue {
this
.
disableCloseReopenButton
(
$button
);
url
=
$button
.
attr
(
'
href
'
);
return
axios
.
put
(
url
)
return
axios
.
put
(
url
)
.
then
(({
data
})
=>
{
const
isClosed
=
$button
.
hasClass
(
'
btn-close
'
);
this
.
updateTopState
(
isClosed
,
data
);
...
...
@@ -98,7 +108,8 @@ export default class Issue {
.
then
(()
=>
{
this
.
disableCloseReopenButton
(
$button
,
false
);
});
});
},
);
}
initCloseReopenReport
()
{
...
...
@@ -124,7 +135,7 @@ export default class Issue {
static
submitNoteForm
(
form
)
{
var
noteText
;
noteText
=
form
.
find
(
"
textarea.js-note-text
"
).
val
();
noteText
=
form
.
find
(
'
textarea.js-note-text
'
).
val
();
if
(
noteText
&&
noteText
.
trim
().
length
>
0
)
{
return
form
.
submit
();
}
...
...
@@ -133,22 +144,26 @@ export default class Issue {
static
initMergeRequests
()
{
var
$container
;
$container
=
$
(
'
#merge-requests
'
);
return
axios
.
get
(
$container
.
data
(
'
url
'
))
return
axios
.
get
(
$container
.
data
(
'
url
'
))
.
then
(({
data
})
=>
{
if
(
'
html
'
in
data
)
{
$container
.
html
(
data
.
html
);
}
}).
catch
(()
=>
flash
(
'
Failed to load referenced merge requests
'
));
})
.
catch
(()
=>
flash
(
'
Failed to load referenced merge requests
'
));
}
static
initRelatedBranches
()
{
var
$container
;
$container
=
$
(
'
#related-branches
'
);
return
axios
.
get
(
$container
.
data
(
'
url
'
))
return
axios
.
get
(
$container
.
data
(
'
url
'
))
.
then
(({
data
})
=>
{
if
(
'
html
'
in
data
)
{
$container
.
html
(
data
.
html
);
}
}).
catch
(()
=>
flash
(
'
Failed to load related branches
'
));
})
.
catch
(()
=>
flash
(
'
Failed to load related branches
'
));
}
}
app/assets/javascripts/job.js
View file @
c559bcca
...
...
@@ -42,9 +42,7 @@ export default class Job extends LogOutputBehaviours {
this
.
scrollThrottled
=
_
.
throttle
(
this
.
toggleScroll
.
bind
(
this
),
100
);
this
.
$window
.
off
(
'
scroll
'
)
.
on
(
'
scroll
'
,
()
=>
{
this
.
$window
.
off
(
'
scroll
'
).
on
(
'
scroll
'
,
()
=>
{
if
(
!
isScrolledToBottom
())
{
this
.
toggleScrollAnimation
(
false
);
}
else
if
(
isScrolledToBottom
()
&&
!
this
.
isLogComplete
)
{
...
...
@@ -87,10 +85,11 @@ export default class Job extends LogOutputBehaviours {
}
getBuildTrace
()
{
return
axios
.
get
(
`
${
this
.
pagePath
}
/trace.json`
,
{
return
axios
.
get
(
`
${
this
.
pagePath
}
/trace.json`
,
{
params
:
{
state
:
this
.
state
},
})
.
then
(
(
res
)
=>
{
.
then
(
res
=>
{
const
log
=
res
.
data
;
if
(
!
this
.
fetchingStatusFavicon
)
{
...
...
@@ -186,5 +185,4 @@ export default class Job extends LogOutputBehaviours {
sidebarOnClick
()
{
if
(
this
.
shouldHideSidebarForViewport
())
this
.
toggleSidebar
();
}
}
app/assets/javascripts/label_manager.js
View file @
c559bcca
...
...
@@ -47,7 +47,10 @@ export default class LabelManager {
}
toggleEmptyState
(
$label
,
$btn
,
action
)
{
this
.
emptyState
.
classList
.
toggle
(
'
hidden
'
,
!!
this
.
prioritizedLabels
[
0
].
querySelector
(
'
:scope > li
'
));
this
.
emptyState
.
classList
.
toggle
(
'
hidden
'
,
!!
this
.
prioritizedLabels
[
0
].
querySelector
(
'
:scope > li
'
),
);
}
toggleLabelPriority
(
$label
,
action
,
persistState
)
{
...
...
@@ -80,16 +83,14 @@ export default class LabelManager {
return
;
}
if
(
action
===
'
remove
'
)
{
axios
.
delete
(
url
)
.
catch
(
rollbackLabelPosition
);
axios
.
delete
(
url
).
catch
(
rollbackLabelPosition
);
// Restore empty message
if
(
!
$from
.
find
(
'
li
'
).
length
)
{
$from
.
find
(
'
.empty-message
'
).
removeClass
(
'
hidden
'
);
}
}
else
{
this
.
savePrioritySort
(
$label
,
action
)
.
catch
(
rollbackLabelPosition
);
this
.
savePrioritySort
(
$label
,
action
).
catch
(
rollbackLabelPosition
);
}
}
...
...
@@ -102,8 +103,7 @@ export default class LabelManager {
}
onPrioritySortUpdate
()
{
this
.
savePrioritySort
()
.
catch
(()
=>
flash
(
this
.
errorMessage
));
this
.
savePrioritySort
().
catch
(()
=>
flash
(
this
.
errorMessage
));
}
savePrioritySort
()
{
...
...
app/assets/javascripts/labels.js
View file @
c559bcca
app/assets/javascripts/layout_nav.js
View file @
c559bcca
...
...
@@ -5,7 +5,9 @@ import initFlyOutNav from './fly_out_nav';
function
hideEndFade
(
$scrollingTabs
)
{
$scrollingTabs
.
each
(
function
scrollTabsLoop
()
{
const
$this
=
$
(
this
);
$this
.
siblings
(
'
.fade-right
'
).
toggleClass
(
'
scrolling
'
,
Math
.
round
(
$this
.
width
())
<
$this
.
prop
(
'
scrollWidth
'
));
$this
.
siblings
(
'
.fade-right
'
)
.
toggleClass
(
'
scrolling
'
,
Math
.
round
(
$this
.
width
())
<
$this
.
prop
(
'
scrollWidth
'
));
});
}
...
...
@@ -15,13 +17,16 @@ export default function initLayoutNav() {
initFlyOutNav
();
$
(
document
).
on
(
'
init.scrolling-tabs
'
,
()
=>
{
$
(
document
)
.
on
(
'
init.scrolling-tabs
'
,
()
=>
{
const
$scrollingTabs
=
$
(
'
.scrolling-tabs
'
).
not
(
'
.is-initialized
'
);
$scrollingTabs
.
addClass
(
'
is-initialized
'
);
$
(
window
).
on
(
'
resize.nav
'
,
()
=>
{
$
(
window
)
.
on
(
'
resize.nav
'
,
()
=>
{
hideEndFade
(
$scrollingTabs
);
}).
trigger
(
'
resize.nav
'
);
})
.
trigger
(
'
resize.nav
'
);
$scrollingTabs
.
on
(
'
scroll
'
,
function
tabsScrollEvent
()
{
const
$this
=
$
(
this
);
...
...
@@ -42,11 +47,12 @@ export default function initLayoutNav() {
const
offset
=
$active
.
offset
().
left
+
activeWidth
;
if
(
offset
>
scrollingTabWidth
-
30
)
{
const
scrollLeft
=
(
offset
-
(
scrollingTabWidth
/
2
))
-
(
activeWidth
/
2
)
;
const
scrollLeft
=
offset
-
scrollingTabWidth
/
2
-
activeWidth
/
2
;
$this
.
scrollLeft
(
scrollLeft
);
}
}
});
}).
trigger
(
'
init.scrolling-tabs
'
);
})
.
trigger
(
'
init.scrolling-tabs
'
);
}
app/assets/javascripts/line_highlighter.js
View file @
c559bcca
...
...
@@ -70,7 +70,7 @@ LineHighlighter.prototype.highlightHash = function(newHash) {
const
scrollOptions
=
{
// Scroll to the first highlighted line on initial load
// Offset -50 for the sticky top bar, and another -100 for some context
offset
:
-
150
offset
:
-
150
,
};
if
(
this
.
options
.
scrollFileHolder
)
{
$
(
this
.
options
.
fileHolderSelector
).
scrollTo
(
lineSelector
,
scrollOptions
);
...
...
@@ -85,7 +85,9 @@ LineHighlighter.prototype.clickHandler = function(event) {
var
current
,
lineNumber
,
range
;
event
.
preventDefault
();
this
.
clearHighlight
();
lineNumber
=
$
(
event
.
target
).
closest
(
'
a
'
).
data
(
'
lineNumber
'
);
lineNumber
=
$
(
event
.
target
)
.
closest
(
'
a
'
)
.
data
(
'
lineNumber
'
);
current
=
this
.
hashToRange
(
this
.
_hash
);
if
(
!
(
current
[
0
]
&&
event
.
shiftKey
))
{
// If there's no current selection, or there is but Shift wasn't held,
...
...
@@ -104,7 +106,7 @@ LineHighlighter.prototype.clickHandler = function(event) {
};
LineHighlighter
.
prototype
.
clearHighlight
=
function
()
{
return
$
(
"
.
"
+
this
.
highlightLineClass
).
removeClass
(
this
.
highlightLineClass
);
return
$
(
'
.
'
+
this
.
highlightLineClass
).
removeClass
(
this
.
highlightLineClass
);
};
// Convert a URL hash String into line numbers
...
...
@@ -135,7 +137,7 @@ LineHighlighter.prototype.hashToRange = function(hash) {
//
// lineNumber - Line number to highlight
LineHighlighter
.
prototype
.
highlightLine
=
function
(
lineNumber
)
{
return
$
(
"
#LC
"
+
lineNumber
).
addClass
(
this
.
highlightLineClass
);
return
$
(
'
#LC
'
+
lineNumber
).
addClass
(
this
.
highlightLineClass
);
};
// Highlight all lines within a range
...
...
@@ -160,9 +162,9 @@ LineHighlighter.prototype.highlightRange = function(range) {
LineHighlighter
.
prototype
.
setHash
=
function
(
firstLineNumber
,
lastLineNumber
)
{
var
hash
;
if
(
lastLineNumber
)
{
hash
=
"
#L
"
+
firstLineNumber
+
"
-
"
+
lastLineNumber
;
hash
=
'
#L
'
+
firstLineNumber
+
'
-
'
+
lastLineNumber
;
}
else
{
hash
=
"
#L
"
+
firstLineNumber
;
hash
=
'
#L
'
+
firstLineNumber
;
}
this
.
_hash
=
hash
;
return
this
.
__setLocationHash__
(
hash
);
...
...
@@ -172,11 +174,15 @@ LineHighlighter.prototype.setHash = function(firstLineNumber, lastLineNumber) {
//
// This method is stubbed in tests.
LineHighlighter
.
prototype
.
__setLocationHash__
=
function
(
value
)
{
return
window
.
history
.
pushState
({
url
:
value
return
window
.
history
.
pushState
(
{
url
:
value
,
// We're using pushState instead of assigning location.hash directly to
// prevent the page from scrolling on the hashchange event
},
document
.
title
,
value
);
},
document
.
title
,
value
,
);
};
export
default
LineHighlighter
;
app/assets/javascripts/locale/sprintf.js
View file @
c559bcca
...
...
@@ -15,7 +15,7 @@ export default (input, parameters, escapeParameters = true) => {
let
output
=
input
;
if
(
parameters
)
{
Object
.
keys
(
parameters
).
forEach
(
(
parameterName
)
=>
{
Object
.
keys
(
parameters
).
forEach
(
parameterName
=>
{
const
parameterValue
=
parameters
[
parameterName
];
const
escapedParameterValue
=
escapeParameters
?
_
.
escape
(
parameterValue
)
:
parameterValue
;
output
=
output
.
replace
(
new
RegExp
(
`%{
${
parameterName
}
}`
,
'
g
'
),
escapedParameterValue
);
...
...
app/assets/javascripts/member_expiration_date.js
View file @
c559bcca
...
...
@@ -9,7 +9,9 @@ import { parsePikadayDate, pikadayToString } from './lib/utils/datefix';
//
export
default
function
memberExpirationDate
(
selector
=
'
.js-access-expiration-date
'
)
{
function
toggleClearInput
()
{
$
(
this
).
closest
(
'
.clearable-input
'
).
toggleClass
(
'
has-value
'
,
$
(
this
).
val
()
!==
''
);
$
(
this
)
.
closest
(
'
.clearable-input
'
)
.
toggleClass
(
'
has-value
'
,
$
(
this
).
val
()
!==
''
);
}
const
inputs
=
$
(
selector
);
...
...
@@ -40,7 +42,9 @@ export default function memberExpirationDate(selector = '.js-access-expiration-d
inputs
.
next
(
'
.js-clear-input
'
).
on
(
'
click
'
,
function
clicked
(
event
)
{
event
.
preventDefault
();
const
input
=
$
(
this
).
closest
(
'
.clearable-input
'
).
find
(
selector
);
const
input
=
$
(
this
)
.
closest
(
'
.clearable-input
'
)
.
find
(
selector
);
const
calendar
=
input
.
data
(
'
pikaday
'
);
calendar
.
setDate
(
null
);
...
...
app/assets/javascripts/merge_request.js
View file @
c559bcca
...
...
@@ -16,26 +16,29 @@ function MergeRequest(opts) {
this
.
opts
=
opts
!=
null
?
opts
:
{};
this
.
submitNoteForm
=
this
.
submitNoteForm
.
bind
(
this
);
this
.
$el
=
$
(
'
.merge-request
'
);
this
.
$
(
'
.show-all-commits
'
).
on
(
'
click
'
,
(
function
(
_this
)
{
this
.
$
(
'
.show-all-commits
'
).
on
(
'
click
'
,
(
function
(
_this
)
{
return
function
()
{
return
_this
.
showAllCommits
();
};
})(
this
));
})(
this
),
);
this
.
initTabs
();
this
.
initMRBtnListeners
();
this
.
initCommitMessageListeners
();
this
.
closeReopenReportToggle
=
IssuablesHelper
.
initCloseReopenReport
();
if
(
$
(
"
a.btn-close
"
).
length
)
{
if
(
$
(
'
a.btn-close
'
).
length
)
{
this
.
taskList
=
new
TaskList
({
dataType
:
'
merge_request
'
,
fieldName
:
'
description
'
,
selector
:
'
.detail-page-description
'
,
onSuccess
:
(
result
)
=>
{
onSuccess
:
result
=>
{
document
.
querySelector
(
'
#task_status
'
).
innerText
=
result
.
task_status
;
document
.
querySelector
(
'
#task_status_short
'
).
innerText
=
result
.
task_status_short
;
}
}
,
});
}
}
...
...
@@ -84,7 +87,7 @@ MergeRequest.prototype.initMRBtnListeners = function() {
MergeRequest
.
prototype
.
submitNoteForm
=
function
(
form
,
$button
)
{
var
noteText
;
noteText
=
form
.
find
(
"
textarea.js-note-text
"
).
val
();
noteText
=
form
.
find
(
'
textarea.js-note-text
'
).
val
();
if
(
noteText
.
trim
().
length
>
0
)
{
form
.
submit
();
$button
.
data
(
'
submitted
'
,
true
);
...
...
@@ -122,7 +125,7 @@ MergeRequest.setStatusBoxToMerged = function() {
MergeRequest
.
decreaseCounter
=
function
(
by
=
1
)
{
const
$el
=
$
(
'
.js-merge-counter
'
);
const
count
=
Math
.
max
(
(
parseInt
(
$el
.
text
().
replace
(
/
[^\d]
/
,
''
),
10
)
-
by
)
,
0
);
const
count
=
Math
.
max
(
parseInt
(
$el
.
text
().
replace
(
/
[^\d]
/
,
''
),
10
)
-
by
,
0
);
$el
.
text
(
addDelimiter
(
count
));
};
...
...
app/assets/javascripts/milestone.js
View file @
c559bcca
...
...
@@ -15,7 +15,7 @@ export default class Milestone {
}
bindTabsSwitching
()
{
return
$
(
'
a[data-toggle="tab"]
'
).
on
(
'
show.bs.tab
'
,
(
e
)
=>
{
return
$
(
'
a[data-toggle="tab"]
'
).
on
(
'
show.bs.tab
'
,
e
=>
{
const
$target
=
$
(
e
.
target
);
window
.
location
.
hash
=
$target
.
attr
(
'
href
'
);
...
...
@@ -36,7 +36,8 @@ export default class Milestone {
const
tabElId
=
$target
.
attr
(
'
href
'
);
if
(
endpoint
&&
!
$target
.
hasClass
(
'
is-loaded
'
))
{
axios
.
get
(
endpoint
)
axios
.
get
(
endpoint
)
.
then
(({
data
})
=>
{
$
(
tabElId
).
html
(
data
.
html
);
$target
.
addClass
(
'
is-loaded
'
);
...
...
@@ -46,15 +47,20 @@ export default class Milestone {
}
static
initDeprecationMessage
()
{
const
deprecationMesssageContainer
=
document
.
querySelector
(
'
.js-milestone-deprecation-message
'
);
const
deprecationMesssageContainer
=
document
.
querySelector
(
'
.js-milestone-deprecation-message
'
,
);
if
(
!
deprecationMesssageContainer
)
return
;
const
deprecationMessage
=
deprecationMesssageContainer
.
querySelector
(
'
.js-milestone-deprecation-message-template
'
).
innerHTML
;
const
deprecationMessage
=
deprecationMesssageContainer
.
querySelector
(
'
.js-milestone-deprecation-message-template
'
,
).
innerHTML
;
const
$popover
=
$
(
'
.js-popover-link
'
,
deprecationMesssageContainer
);
const
hideOnScroll
=
togglePopover
.
bind
(
$popover
,
false
);
$popover
.
popover
({
$popover
.
popover
({
content
:
deprecationMessage
,
html
:
true
,
placement
:
'
bottom
'
,
...
...
app/assets/javascripts/mini_pipeline_graph_dropdown.js
View file @
c559bcca
...
...
@@ -46,7 +46,7 @@ export default class MiniPipelineGraph {
$
(
document
).
on
(
'
click
'
,
`
${
this
.
container
}
.js-builds-dropdown-list a.mini-pipeline-graph-dropdown-item`
,
(
e
)
=>
{
e
=>
{
e
.
stopPropagation
();
},
);
...
...
@@ -82,7 +82,8 @@ export default class MiniPipelineGraph {
this
.
renderBuildsList
(
button
,
''
);
this
.
toggleLoading
(
button
);
axios
.
get
(
endpoint
)
axios
.
get
(
endpoint
)
.
then
(({
data
})
=>
{
this
.
toggleLoading
(
button
);
this
.
renderBuildsList
(
button
,
data
.
html
);
...
...
@@ -90,7 +91,11 @@ export default class MiniPipelineGraph {
})
.
catch
(()
=>
{
this
.
toggleLoading
(
button
);
if
(
$
(
button
).
parent
().
hasClass
(
'
open
'
))
{
if
(
$
(
button
)
.
parent
()
.
hasClass
(
'
open
'
)
)
{
$
(
button
).
dropdown
(
'
toggle
'
);
}
flash
(
'
An error occurred while fetching the builds.
'
,
'
alert
'
);
...
...
@@ -104,8 +109,8 @@ export default class MiniPipelineGraph {
* @return {type}
*/
toggleLoading
(
stageContainer
)
{
stageContainer
.
parentElement
.
querySelector
(
`
${
this
.
dropdownListSelector
}
.js-builds-dropdown-loading`
,
)
.
classList
.
toggle
(
'
hidden
'
);
stageContainer
.
parentElement
.
querySelector
(
`
${
this
.
dropdownListSelector
}
.js-builds-dropdown-loading`
)
.
classList
.
toggle
(
'
hidden
'
);
}
}
app/assets/javascripts/namespace_select.js
View file @
c559bcca
...
...
@@ -14,14 +14,14 @@ export default class NamespaceSelect {
selectable
:
true
,
filterRemote
:
true
,
search
:
{
fields
:
[
'
path
'
]
fields
:
[
'
path
'
]
,
},
fieldName
:
fieldName
,
toggleLabel
:
function
(
selected
)
{
if
(
selected
.
id
==
null
)
{
return
selected
.
text
;
}
else
{
return
selected
.
kind
+
"
:
"
+
selected
.
full_path
;
return
selected
.
kind
+
'
:
'
+
selected
.
full_path
;
}
},
data
:
function
(
term
,
dataCallback
)
{
...
...
@@ -29,7 +29,7 @@ export default class NamespaceSelect {
if
(
isFilter
)
{
const
anyNamespace
=
{
text
:
'
Any namespace
'
,
id
:
null
id
:
null
,
};
namespaces
.
unshift
(
anyNamespace
);
namespaces
.
splice
(
1
,
0
,
'
divider
'
);
...
...
@@ -41,7 +41,7 @@ export default class NamespaceSelect {
if
(
namespace
.
id
==
null
)
{
return
namespace
.
text
;
}
else
{
return
namespace
.
kind
+
"
:
"
+
namespace
.
full_path
;
return
namespace
.
kind
+
'
:
'
+
namespace
.
full_path
;
}
},
renderRow
:
this
.
renderRow
,
...
...
app/assets/javascripts/network/branch_graph.js
View file @
c559bcca
...
...
@@ -20,7 +20,7 @@ export default (function() {
this
.
mtime
=
0
;
this
.
mspace
=
0
;
this
.
parents
=
{};
this
.
colors
=
[
"
#000
"
];
this
.
colors
=
[
'
#000
'
];
this
.
offsetX
=
150
;
this
.
offsetY
=
20
;
this
.
unitTime
=
30
;
...
...
@@ -30,9 +30,10 @@ export default (function() {
}
BranchGraph
.
prototype
.
load
=
function
()
{
axios
.
get
(
this
.
options
.
url
)
axios
.
get
(
this
.
options
.
url
)
.
then
(({
data
})
=>
{
$
(
"
.loading
"
,
this
.
element
).
hide
();
$
(
'
.loading
'
,
this
.
element
).
hide
();
this
.
prepareData
(
data
.
days
,
data
.
commits
);
this
.
buildGraph
();
})
...
...
@@ -71,17 +72,19 @@ export default (function() {
c
=
ref
[
j
];
this
.
mtime
=
Math
.
max
(
this
.
mtime
,
c
.
time
);
this
.
mspace
=
Math
.
max
(
this
.
mspace
,
c
.
space
);
results
.
push
((
function
()
{
results
.
push
(
function
()
{
var
l
,
len1
,
ref1
,
results1
;
ref1
=
c
.
parents
;
results1
=
[];
for
(
l
=
0
,
len1
=
ref1
.
length
;
l
<
len1
;
l
+=
1
)
{
p
=
ref1
[
l
];
this
.
parents
[
p
[
0
]]
=
true
;
results1
.
push
(
this
.
mspace
=
Math
.
max
(
this
.
mspace
,
p
[
1
]
));
results1
.
push
((
this
.
mspace
=
Math
.
max
(
this
.
mspace
,
p
[
1
])
));
}
return
results1
;
}).
call
(
this
));
}.
call
(
this
),
);
}
return
results
;
};
...
...
@@ -91,11 +94,11 @@ export default (function() {
k
=
0
;
results
=
[];
while
(
k
<
this
.
mspace
)
{
this
.
colors
.
push
(
Raphael
.
getColor
(.
8
));
this
.
colors
.
push
(
Raphael
.
getColor
(
0
.8
));
// Skipping a few colors in the spectrum to get more contrast between colors
Raphael
.
getColor
();
Raphael
.
getColor
();
results
.
push
(
k
+=
1
);
results
.
push
(
(
k
+=
1
)
);
}
return
results
;
};
...
...
@@ -104,12 +107,12 @@ export default (function() {
var
cuday
,
cumonth
,
day
,
j
,
len
,
mm
,
ref
;
const
{
r
}
=
this
;
cuday
=
0
;
cumonth
=
""
;
cumonth
=
''
;
r
.
rect
(
0
,
0
,
40
,
this
.
barHeight
).
attr
({
fill
:
"
#222
"
fill
:
'
#222
'
,
});
r
.
rect
(
40
,
0
,
30
,
this
.
barHeight
).
attr
({
fill
:
"
#444
"
fill
:
'
#444
'
,
});
ref
=
this
.
days
;
...
...
@@ -118,16 +121,16 @@ export default (function() {
if
(
cuday
!==
day
[
0
]
||
cumonth
!==
day
[
1
])
{
// Dates
r
.
text
(
55
,
this
.
offsetY
+
this
.
unitTime
*
mm
,
day
[
0
]).
attr
({
font
:
"
12px Monaco, monospace
"
,
fill
:
"
#BBB
"
font
:
'
12px Monaco, monospace
'
,
fill
:
'
#BBB
'
,
});
[
cuday
]
=
day
;
}
if
(
cumonth
!==
day
[
1
])
{
// Months
r
.
text
(
20
,
this
.
offsetY
+
this
.
unitTime
*
mm
,
day
[
1
]).
attr
({
font
:
"
12px Monaco, monospace
"
,
fill
:
"
#EEE
"
font
:
'
12px Monaco, monospace
'
,
fill
:
'
#EEE
'
,
});
// eslint-disable-next-line prefer-destructuring
...
...
@@ -173,11 +176,13 @@ export default (function() {
BranchGraph
.
prototype
.
bindEvents
=
function
()
{
const
{
element
}
=
this
;
return
$
(
element
).
scroll
((
function
(
_this
)
{
return
$
(
element
).
scroll
(
(
function
(
_this
)
{
return
function
(
event
)
{
return
_this
.
renderPartialGraph
();
};
})(
this
));
})(
this
),
);
};
BranchGraph
.
prototype
.
scrollDown
=
function
()
{
...
...
@@ -219,46 +224,53 @@ export default (function() {
shortrefs
=
commit
.
refs
;
// Truncate if longer than 15 chars
if
(
shortrefs
.
length
>
17
)
{
shortrefs
=
shortrefs
.
substr
(
0
,
15
)
+
"
…
"
;
shortrefs
=
shortrefs
.
substr
(
0
,
15
)
+
'
…
'
;
}
text
=
r
.
text
(
x
+
4
,
y
,
shortrefs
).
attr
({
"
text-anchor
"
:
"
start
"
,
font
:
"
10px Monaco, monospace
"
,
fill
:
"
#FFF
"
,
title
:
commit
.
refs
'
text-anchor
'
:
'
start
'
,
font
:
'
10px Monaco, monospace
'
,
fill
:
'
#FFF
'
,
title
:
commit
.
refs
,
});
textbox
=
text
.
getBBox
();
// Create rectangle based on the size of the textbox
rect
=
r
.
rect
(
x
,
y
-
7
,
textbox
.
width
+
5
,
textbox
.
height
+
5
,
4
).
attr
({
fill
:
"
#000
"
,
"
fill-opacity
"
:
.
5
,
stroke
:
"
none
"
fill
:
'
#000
'
,
'
fill-opacity
'
:
0
.5
,
stroke
:
'
none
'
,
});
triangle
=
r
.
path
([
"
M
"
,
x
-
5
,
y
,
"
L
"
,
x
-
15
,
y
-
4
,
"
L
"
,
x
-
15
,
y
+
4
,
"
Z
"
]).
attr
({
fill
:
"
#000
"
,
"
fill-opacity
"
:
.
5
,
stroke
:
"
none
"
triangle
=
r
.
path
([
'
M
'
,
x
-
5
,
y
,
'
L
'
,
x
-
15
,
y
-
4
,
'
L
'
,
x
-
15
,
y
+
4
,
'
Z
'
]).
attr
({
fill
:
'
#000
'
,
'
fill-opacity
'
:
0
.5
,
stroke
:
'
none
'
,
});
label
=
r
.
set
(
rect
,
text
);
label
.
transform
([
"
t
"
,
-
rect
.
getBBox
().
width
-
15
,
0
]);
label
.
transform
([
'
t
'
,
-
rect
.
getBBox
().
width
-
15
,
0
]);
// Set text to front
return
text
.
toFront
();
};
BranchGraph
.
prototype
.
appendAnchor
=
function
(
x
,
y
,
commit
)
{
const
{
r
,
top
,
options
}
=
this
;
const
anchor
=
r
.
circle
(
x
,
y
,
10
).
attr
({
fill
:
"
#000
"
,
const
anchor
=
r
.
circle
(
x
,
y
,
10
)
.
attr
({
fill
:
'
#000
'
,
opacity
:
0
,
cursor
:
"
pointer
"
}).
click
(
function
()
{
return
window
.
open
(
options
.
commit_url
.
replace
(
"
%s
"
,
commit
.
id
),
"
_blank
"
);
}).
hover
(
function
()
{
cursor
:
'
pointer
'
,
})
.
click
(
function
()
{
return
window
.
open
(
options
.
commit_url
.
replace
(
'
%s
'
,
commit
.
id
),
'
_blank
'
);
})
.
hover
(
function
()
{
this
.
tooltip
=
r
.
commitTooltip
(
x
+
5
,
y
,
commit
);
return
top
.
push
(
this
.
tooltip
.
insertBefore
(
this
));
},
function
()
{
},
function
()
{
return
this
.
tooltip
&&
this
.
tooltip
.
remove
()
&&
delete
this
.
tooltip
;
});
},
);
return
top
.
push
(
anchor
);
};
...
...
@@ -266,7 +278,7 @@ export default (function() {
const
{
r
}
=
this
;
r
.
circle
(
x
,
y
,
3
).
attr
({
fill
:
this
.
colors
[
commit
.
space
],
stroke
:
"
none
"
stroke
:
'
none
'
,
});
const
avatar_box_x
=
this
.
offsetX
+
this
.
unitSpace
*
this
.
mspace
+
10
;
...
...
@@ -274,12 +286,14 @@ export default (function() {
r
.
rect
(
avatar_box_x
,
avatar_box_y
,
20
,
20
).
attr
({
stroke
:
this
.
colors
[
commit
.
space
],
"
stroke-width
"
:
2
'
stroke-width
'
:
2
,
});
r
.
image
(
commit
.
author
.
icon
,
avatar_box_x
,
avatar_box_y
,
20
,
20
);
return
r
.
text
(
this
.
offsetX
+
this
.
unitSpace
*
this
.
mspace
+
35
,
y
,
commit
.
message
.
split
(
"
\n
"
)[
0
]).
attr
({
"
text-anchor
"
:
"
start
"
,
font
:
"
14px Monaco, monospace
"
return
r
.
text
(
this
.
offsetX
+
this
.
unitSpace
*
this
.
mspace
+
35
,
y
,
commit
.
message
.
split
(
'
\n
'
)[
0
])
.
attr
({
'
text-anchor
'
:
'
start
'
,
font
:
'
14px Monaco, monospace
'
,
});
};
...
...
@@ -304,30 +318,32 @@ export default (function() {
// Build line shape
if
(
parent
[
1
]
===
commit
.
space
)
{
offset
=
[
0
,
5
];
arrow
=
"
l-2,5,4,0,-2,-5,0,5
"
;
arrow
=
'
l-2,5,4,0,-2,-5,0,5
'
;
}
else
if
(
parent
[
1
]
<
commit
.
space
)
{
offset
=
[
3
,
3
];
arrow
=
"
l5,0,-2,4,-3,-4,4,2
"
;
arrow
=
'
l5,0,-2,4,-3,-4,4,2
'
;
}
else
{
offset
=
[
-
3
,
3
];
arrow
=
"
l-5,0,2,4,3,-4,-4,2
"
;
arrow
=
'
l-5,0,2,4,3,-4,-4,2
'
;
}
// Start point
route
=
[
"
M
"
,
x
+
offset
[
0
],
y
+
offset
[
1
]];
route
=
[
'
M
'
,
x
+
offset
[
0
],
y
+
offset
[
1
]];
// Add arrow if not first parent
if
(
i
>
0
)
{
route
.
push
(
arrow
);
}
// Circumvent if overlap
if
(
commit
.
space
!==
parentCommit
.
space
||
commit
.
space
!==
parent
[
1
])
{
route
.
push
(
"
L
"
,
parentX2
,
y
+
10
,
"
L
"
,
parentX2
,
parentY
-
5
);
route
.
push
(
'
L
'
,
parentX2
,
y
+
10
,
'
L
'
,
parentX2
,
parentY
-
5
);
}
// End point
route
.
push
(
"
L
"
,
parentX1
,
parentY
);
results
.
push
(
r
.
path
(
route
).
attr
({
route
.
push
(
'
L
'
,
parentX1
,
parentY
);
results
.
push
(
r
.
path
(
route
).
attr
({
stroke
:
color
,
"
stroke-width
"
:
2
}));
'
stroke-width
'
:
2
,
}),
);
}
return
results
;
};
...
...
@@ -337,10 +353,10 @@ export default (function() {
const
{
r
}
=
this
;
const
x
=
this
.
offsetX
+
this
.
unitSpace
*
(
this
.
mspace
-
commit
.
space
);
const
y
=
this
.
offsetY
+
this
.
unitTime
*
commit
.
time
;
r
.
path
([
"
M
"
,
x
+
5
,
y
,
"
L
"
,
x
+
15
,
y
+
4
,
"
L
"
,
x
+
15
,
y
-
4
,
"
Z
"
]).
attr
({
fill
:
"
#000
"
,
"
fill-opacity
"
:
.
5
,
stroke
:
"
none
"
r
.
path
([
'
M
'
,
x
+
5
,
y
,
'
L
'
,
x
+
15
,
y
+
4
,
'
L
'
,
x
+
15
,
y
-
4
,
'
Z
'
]).
attr
({
fill
:
'
#000
'
,
'
fill-opacity
'
:
0
.5
,
stroke
:
'
none
'
,
});
// Displayed in the center
return
this
.
element
.
scrollTop
(
y
-
this
.
graphHeight
/
2
);
...
...
app/assets/javascripts/network/raphael.js
View file @
c559bcca
...
...
@@ -49,7 +49,7 @@ Raphael.prototype.textWrap = function testWrap(t, width) {
const
s
=
[];
for
(
let
j
=
0
,
len
=
words
.
length
;
j
<
len
;
j
+=
1
)
{
const
word
=
words
[
j
];
if
(
x
+
(
word
.
length
*
letterWidth
)
>
width
)
{
if
(
x
+
word
.
length
*
letterWidth
>
width
)
{
s
.
push
(
'
\n
'
);
x
=
0
;
}
...
...
app/assets/javascripts/new_branch_form.js
View file @
c559bcca
...
...
@@ -30,24 +30,24 @@ export default class NewBranchForm {
startsWith
=
{
pattern
:
/^
(\/
|
\.)
/g
,
prefix
:
"
can't start with
"
,
conjunction
:
"
or
"
conjunction
:
'
or
'
,
};
endsWith
=
{
pattern
:
/
(\/
|
\.
|
\.
lock
)
$/g
,
prefix
:
"
can't end in
"
,
conjunction
:
"
or
"
conjunction
:
'
or
'
,
};
invalid
=
{
pattern
:
/
(\s
|~|
\^
|:|
\?
|
\*
|
\[
|
\\
|
\.\.
|@
\{
|
\/{2,}){1}
/g
,
prefix
:
"
can't contain
"
,
conjunction
:
"
,
"
conjunction
:
'
,
'
,
};
single
=
{
pattern
:
/^@+$/g
,
prefix
:
"
can't be
"
,
conjunction
:
"
or
"
conjunction
:
'
or
'
,
};
return
this
.
restrictions
=
[
startsWith
,
invalid
,
endsWith
,
single
]
;
return
(
this
.
restrictions
=
[
startsWith
,
invalid
,
endsWith
,
single
])
;
}
validate
()
{
...
...
@@ -73,7 +73,7 @@ export default class NewBranchForm {
return
"
'
"
+
value
+
"
'
"
;
}
});
return
restriction
.
prefix
+
"
"
+
(
formatted
.
join
(
restriction
.
conjunction
)
);
return
restriction
.
prefix
+
'
'
+
formatted
.
join
(
restriction
.
conjunction
);
};
validator
=
(
function
(
_this
)
{
return
function
(
errors
,
restriction
)
{
...
...
@@ -88,7 +88,7 @@ export default class NewBranchForm {
})(
this
);
errors
=
this
.
restrictions
.
reduce
(
validator
,
[]);
if
(
errors
.
length
>
0
)
{
errorMessage
=
$
(
"
<span/>
"
).
text
(
errors
.
join
(
'
,
'
));
errorMessage
=
$
(
'
<span/>
'
).
text
(
errors
.
join
(
'
,
'
));
return
this
.
branchNameError
.
append
(
errorMessage
);
}
}
...
...
app/assets/javascripts/new_commit_form.js
View file @
c559bcca
...
...
@@ -6,9 +6,7 @@ export default class NewCommitForm {
this
.
branchName
=
form
.
find
(
'
.js-branch-name
'
);
this
.
originalBranch
=
form
.
find
(
'
.js-original-branch
'
);
this
.
createMergeRequest
=
form
.
find
(
'
.js-create-merge-request
'
);
this
.
createMergeRequestContainer
=
form
.
find
(
'
.js-create-merge-request-container
'
,
);
this
.
createMergeRequestContainer
=
form
.
find
(
'
.js-create-merge-request-container
'
);
this
.
branchName
.
keyup
(
this
.
renderDestination
);
this
.
renderDestination
();
}
...
...
app/assets/javascripts/notifications_dropdown.js
View file @
c559bcca
...
...
@@ -18,7 +18,9 @@ export default function notificationsDropdown() {
$
(
document
).
on
(
'
ajax:success
'
,
'
.notification-form
'
,
(
e
,
data
)
=>
{
if
(
data
.
saved
)
{
$
(
e
.
currentTarget
).
closest
(
'
.js-notification-dropdown
'
).
replaceWith
(
data
.
html
);
$
(
e
.
currentTarget
)
.
closest
(
'
.js-notification-dropdown
'
)
.
replaceWith
(
data
.
html
);
}
else
{
Flash
(
'
Failed to save new settings
'
,
'
alert
'
);
}
...
...
app/assets/javascripts/notifications_form.js
View file @
c559bcca
...
...
@@ -22,7 +22,8 @@ export default class NotificationsForm {
// eslint-disable-next-line class-methods-use-this
showCheckboxLoadingSpinner
(
$parent
)
{
$parent
.
addClass
(
'
is-loading
'
)
$parent
.
addClass
(
'
is-loading
'
)
.
find
(
'
.custom-notification-event-loading
'
)
.
removeClass
(
'
fa-check
'
)
.
addClass
(
'
fa-spin fa-spinner
'
)
...
...
@@ -38,9 +39,12 @@ export default class NotificationsForm {
.
then
(({
data
})
=>
{
$checkbox
.
enable
();
if
(
data
.
saved
)
{
$parent
.
find
(
'
.custom-notification-event-loading
'
).
toggleClass
(
'
fa-spin fa-spinner fa-check is-done
'
);
$parent
.
find
(
'
.custom-notification-event-loading
'
)
.
toggleClass
(
'
fa-spin fa-spinner fa-check is-done
'
);
setTimeout
(()
=>
{
$parent
.
removeClass
(
'
is-loading
'
)
$parent
.
removeClass
(
'
is-loading
'
)
.
find
(
'
.custom-notification-event-loading
'
)
.
toggleClass
(
'
fa-spin fa-spinner fa-check is-done
'
);
},
2000
);
...
...
app/assets/javascripts/pager.js
View file @
c559bcca
...
...
@@ -24,12 +24,14 @@ export default {
getOld
()
{
this
.
loading
.
show
();
axios
.
get
(
this
.
url
,
{
axios
.
get
(
this
.
url
,
{
params
:
{
limit
:
this
.
limit
,
offset
:
this
.
offset
,
},
}).
then
(({
data
})
=>
{
})
.
then
(({
data
})
=>
{
this
.
append
(
data
.
count
,
this
.
prepareData
(
data
.
html
));
this
.
callback
();
...
...
@@ -39,7 +41,8 @@ export default {
}
else
{
this
.
loading
.
hide
();
}
}).
catch
(()
=>
this
.
loading
.
hide
());
})
.
catch
(()
=>
this
.
loading
.
hide
());
},
append
(
count
,
html
)
{
...
...
app/assets/javascripts/pdf/index.vue
View file @
c559bcca
<
script
>
import
pdfjsLib
from
'
vendor/pdf
'
;
import
workerSrc
from
'
vendor/pdf.worker.min
'
;
import
pdfjsLib
from
'
vendor/pdf
'
;
import
workerSrc
from
'
vendor/pdf.worker.min
'
;
import
page
from
'
./page/index.vue
'
;
import
page
from
'
./page/index.vue
'
;
export
default
{
export
default
{
components
:
{
page
},
props
:
{
pdf
:
{
...
...
@@ -34,24 +34,25 @@
methods
:
{
load
()
{
this
.
pages
=
[];
return
pdfjsLib
.
getDocument
(
this
.
document
)
return
pdfjsLib
.
getDocument
(
this
.
document
)
.
then
(
this
.
renderPages
)
.
then
(()
=>
this
.
$emit
(
'
pdflabload
'
))
.
catch
(
error
=>
this
.
$emit
(
'
pdflaberror
'
,
error
))
.
then
(()
=>
{
this
.
loading
=
false
;
});
.
then
(()
=>
{
this
.
loading
=
false
;
});
},
renderPages
(
pdf
)
{
const
pagePromises
=
[];
this
.
loading
=
true
;
for
(
let
num
=
1
;
num
<=
pdf
.
numPages
;
num
+=
1
)
{
pagePromises
.
push
(
pdf
.
getPage
(
num
).
then
(
p
=>
this
.
pages
.
push
(
p
)),
);
pagePromises
.
push
(
pdf
.
getPage
(
num
).
then
(
p
=>
this
.
pages
.
push
(
p
)));
}
return
Promise
.
all
(
pagePromises
);
},
},
};
};
</
script
>
<
template
>
...
...
@@ -69,9 +70,9 @@
</
template
>
<
style
>
.pdf-viewer
{
.pdf-viewer
{
background
:
url('./assets/img/bg.gif')
;
display
:
flex
;
flex-flow
:
column
nowrap
;
}
}
</
style
>
app/assets/javascripts/pdf/page/index.vue
View file @
c559bcca
<
script
>
export
default
{
export
default
{
props
:
{
page
:
{
type
:
Object
,
...
...
@@ -34,11 +34,14 @@
this
.
$refs
.
canvas
.
height
=
this
.
viewport
.
height
;
this
.
$refs
.
canvas
.
width
=
this
.
viewport
.
width
;
this
.
rendering
=
true
;
this
.
page
.
render
(
this
.
renderContext
)
.
then
(()
=>
{
this
.
rendering
=
false
;
})
this
.
page
.
render
(
this
.
renderContext
)
.
then
(()
=>
{
this
.
rendering
=
false
;
})
.
catch
(
error
=>
this
.
$emit
(
'
pdflaberror
'
,
error
));
},
};
};
</
script
>
<
template
>
...
...
@@ -51,20 +54,20 @@
</
template
>
<
style
>
.pdf-page
{
.pdf-page
{
margin
:
8px
auto
0
auto
;
border-top
:
1px
#ddd
solid
;
border-bottom
:
1px
#ddd
solid
;
width
:
100%
;
}
}
.pdf-page
:first-child
{
.pdf-page
:first-child
{
margin-top
:
0px
;
border-top
:
0px
;
}
}
.pdf-page
:last-child
{
.pdf-page
:last-child
{
margin-bottom
:
0px
;
border-bottom
:
0px
;
}
}
</
style
>
app/assets/javascripts/pipelines/components/pipelines_table_row.vue
View file @
c559bcca
...
...
@@ -64,10 +64,7 @@ export default {
return
[];
}
const
{
details
}
=
this
.
pipeline
;
return
[
...(
details
.
manual_actions
||
[]),
...(
details
.
scheduled_actions
||
[]),
];
return
[...(
details
.
manual_actions
||
[]),
...(
details
.
scheduled_actions
||
[])];
},
/**
* If provided, returns the commit tag.
...
...
app/assets/javascripts/project_find_file.js
View file @
c559bcca
...
...
@@ -10,14 +10,14 @@ import { __ } from '~/locale';
const
highlighter
=
function
(
element
,
text
,
matches
)
{
var
highlightText
,
j
,
lastIndex
,
len
,
matchIndex
,
matchedChars
,
unmatched
;
lastIndex
=
0
;
highlightText
=
""
;
highlightText
=
''
;
matchedChars
=
[];
for
(
j
=
0
,
len
=
matches
.
length
;
j
<
len
;
j
+=
1
)
{
matchIndex
=
matches
[
j
];
unmatched
=
text
.
substring
(
lastIndex
,
matchIndex
);
if
(
unmatched
)
{
if
(
matchedChars
.
length
)
{
element
.
append
(
matchedChars
.
join
(
""
).
bold
());
element
.
append
(
matchedChars
.
join
(
''
).
bold
());
}
matchedChars
=
[];
element
.
append
(
document
.
createTextNode
(
unmatched
));
...
...
@@ -26,7 +26,7 @@ const highlighter = function(element, text, matches) {
lastIndex
=
matchIndex
+
1
;
}
if
(
matchedChars
.
length
)
{
element
.
append
(
matchedChars
.
join
(
""
).
bold
());
element
.
append
(
matchedChars
.
join
(
''
).
bold
());
}
return
element
.
append
(
document
.
createTextNode
(
text
.
substring
(
lastIndex
)));
};
...
...
@@ -40,7 +40,7 @@ export default class ProjectFindFile {
this
.
selectRowDown
=
this
.
selectRowDown
.
bind
(
this
);
this
.
selectRowUp
=
this
.
selectRowUp
.
bind
(
this
);
this
.
filePaths
=
{};
this
.
inputElement
=
this
.
element
.
find
(
"
.file-finder-input
"
);
this
.
inputElement
=
this
.
element
.
find
(
'
.file-finder-input
'
);
// init event
this
.
initEvent
();
// focus text input box
...
...
@@ -50,38 +50,51 @@ export default class ProjectFindFile {
}
initEvent
()
{
this
.
inputElement
.
off
(
"
keyup
"
);
this
.
inputElement
.
on
(
"
keyup
"
,
(
function
(
_this
)
{
this
.
inputElement
.
off
(
'
keyup
'
);
this
.
inputElement
.
on
(
'
keyup
'
,
(
function
(
_this
)
{
return
function
(
event
)
{
var
oldValue
,
ref
,
target
,
value
;
target
=
$
(
event
.
target
);
value
=
target
.
val
();
oldValue
=
(
ref
=
target
.
data
(
"
oldValue
"
))
!=
null
?
ref
:
""
;
oldValue
=
(
ref
=
target
.
data
(
'
oldValue
'
))
!=
null
?
ref
:
''
;
if
(
value
!==
oldValue
)
{
target
.
data
(
"
oldValue
"
,
value
);
target
.
data
(
'
oldValue
'
,
value
);
_this
.
findFile
();
return
_this
.
element
.
find
(
"
tr.tree-item
"
).
eq
(
0
).
addClass
(
"
selected
"
).
focus
();
return
_this
.
element
.
find
(
'
tr.tree-item
'
)
.
eq
(
0
)
.
addClass
(
'
selected
'
)
.
focus
();
}
};
})(
this
));
})(
this
),
);
}
findFile
()
{
var
result
,
searchText
;
searchText
=
this
.
inputElement
.
val
();
result
=
searchText
.
length
>
0
?
fuzzaldrinPlus
.
filter
(
this
.
filePaths
,
searchText
)
:
this
.
filePaths
;
result
=
searchText
.
length
>
0
?
fuzzaldrinPlus
.
filter
(
this
.
filePaths
,
searchText
)
:
this
.
filePaths
;
return
this
.
renderList
(
result
,
searchText
);
// find file
}
// files pathes load
load
(
url
)
{
axios
.
get
(
url
)
axios
.
get
(
url
)
.
then
(({
data
})
=>
{
this
.
element
.
find
(
'
.loading
'
).
hide
();
this
.
filePaths
=
data
;
this
.
findFile
();
this
.
element
.
find
(
'
.files-slider tr.tree-item
'
).
eq
(
0
).
addClass
(
'
selected
'
).
focus
();
this
.
element
.
find
(
'
.files-slider tr.tree-item
'
)
.
eq
(
0
)
.
addClass
(
'
selected
'
)
.
focus
();
})
.
catch
(()
=>
flash
(
__
(
'
An error occurred while loading filenames
'
)));
}
...
...
@@ -89,7 +102,7 @@ export default class ProjectFindFile {
// render result
renderList
(
filePaths
,
searchText
)
{
var
blobItemUrl
,
filePath
,
html
,
i
,
len
,
matches
,
results
;
this
.
element
.
find
(
"
.tree-table > tbody
"
).
empty
();
this
.
element
.
find
(
'
.tree-table > tbody
'
).
empty
();
results
=
[];
for
(
i
=
0
,
len
=
filePaths
.
length
;
i
<
len
;
i
+=
1
)
{
...
...
@@ -100,9 +113,9 @@ export default class ProjectFindFile {
if
(
searchText
)
{
matches
=
fuzzaldrinPlus
.
match
(
filePath
,
searchText
);
}
blobItemUrl
=
this
.
options
.
blobUrlTemplate
+
"
/
"
+
filePath
;
blobItemUrl
=
this
.
options
.
blobUrlTemplate
+
'
/
'
+
filePath
;
html
=
ProjectFindFile
.
makeHtml
(
filePath
,
matches
,
blobItemUrl
);
results
.
push
(
this
.
element
.
find
(
"
.tree-table > tbody
"
).
append
(
html
));
results
.
push
(
this
.
element
.
find
(
'
.tree-table > tbody
'
).
append
(
html
));
}
return
results
;
}
...
...
@@ -110,52 +123,56 @@ export default class ProjectFindFile {
// make tbody row html
static
makeHtml
(
filePath
,
matches
,
blobItemUrl
)
{
var
$tr
;
$tr
=
$
(
"
<tr class='tree-item'><td class='tree-item-file-name link-container'><a><i class='fa fa-file-text-o fa-fw'></i><span class='str-truncated'></span></a></td></tr>
"
);
$tr
=
$
(
"
<tr class='tree-item'><td class='tree-item-file-name link-container'><a><i class='fa fa-file-text-o fa-fw'></i><span class='str-truncated'></span></a></td></tr>
"
,
);
if
(
matches
)
{
$tr
.
find
(
"
a
"
).
replaceWith
(
highlighter
(
$tr
.
find
(
"
a
"
),
filePath
,
matches
).
attr
(
"
href
"
,
blobItemUrl
));
$tr
.
find
(
'
a
'
)
.
replaceWith
(
highlighter
(
$tr
.
find
(
'
a
'
),
filePath
,
matches
).
attr
(
'
href
'
,
blobItemUrl
));
}
else
{
$tr
.
find
(
"
a
"
).
attr
(
"
href
"
,
blobItemUrl
);
$tr
.
find
(
"
.str-truncated
"
).
text
(
filePath
);
$tr
.
find
(
'
a
'
).
attr
(
'
href
'
,
blobItemUrl
);
$tr
.
find
(
'
.str-truncated
'
).
text
(
filePath
);
}
return
$tr
;
}
selectRow
(
type
)
{
var
next
,
rows
,
selectedRow
;
rows
=
this
.
element
.
find
(
"
.files-slider tr.tree-item
"
);
selectedRow
=
this
.
element
.
find
(
"
.files-slider tr.tree-item.selected
"
);
rows
=
this
.
element
.
find
(
'
.files-slider tr.tree-item
'
);
selectedRow
=
this
.
element
.
find
(
'
.files-slider tr.tree-item.selected
'
);
if
(
rows
&&
rows
.
length
>
0
)
{
if
(
selectedRow
&&
selectedRow
.
length
>
0
)
{
if
(
type
===
"
UP
"
)
{
if
(
type
===
'
UP
'
)
{
next
=
selectedRow
.
prev
();
}
else
if
(
type
===
"
DOWN
"
)
{
}
else
if
(
type
===
'
DOWN
'
)
{
next
=
selectedRow
.
next
();
}
if
(
next
.
length
>
0
)
{
selectedRow
.
removeClass
(
"
selected
"
);
selectedRow
.
removeClass
(
'
selected
'
);
selectedRow
=
next
;
}
}
else
{
selectedRow
=
rows
.
eq
(
0
);
}
return
selectedRow
.
addClass
(
"
selected
"
).
focus
();
return
selectedRow
.
addClass
(
'
selected
'
).
focus
();
}
}
selectRowUp
()
{
return
this
.
selectRow
(
"
UP
"
);
return
this
.
selectRow
(
'
UP
'
);
}
selectRowDown
()
{
return
this
.
selectRow
(
"
DOWN
"
);
return
this
.
selectRow
(
'
DOWN
'
);
}
goToTree
()
{
return
window
.
location
.
href
=
this
.
options
.
treeUrl
;
return
(
window
.
location
.
href
=
this
.
options
.
treeUrl
)
;
}
goToBlob
()
{
var
$link
=
this
.
element
.
find
(
"
.tree-item.selected .tree-item-file-name a
"
);
var
$link
=
this
.
element
.
find
(
'
.tree-item.selected .tree-item-file-name a
'
);
if
(
$link
.
length
)
{
$link
.
get
(
0
).
click
();
...
...
app/assets/javascripts/project_import.js
View file @
c559bcca
...
...
@@ -5,4 +5,3 @@ export default function projectImport() {
visitUrl
(
window
.
location
.
href
);
},
5000
);
}
app/assets/javascripts/project_label_subscription.js
View file @
c559bcca
...
...
@@ -31,7 +31,9 @@ export default class ProjectLabelSubscription {
$btn
.
addClass
(
'
disabled
'
);
axios
.
post
(
url
).
then
(()
=>
{
axios
.
post
(
url
)
.
then
(()
=>
{
let
newStatus
;
let
newAction
;
...
...
@@ -56,7 +58,8 @@ export default class ProjectLabelSubscription {
return
button
;
});
}).
catch
(()
=>
flash
(
__
(
'
There was an error subscribing to this label.
'
)));
})
.
catch
(()
=>
flash
(
__
(
'
There was an error subscribing to this label.
'
)));
}
static
setNewTitle
(
$button
,
originalTitle
,
newStatus
)
{
...
...
app/assets/javascripts/project_select.js
View file @
c559bcca
...
...
@@ -16,28 +16,28 @@ export default function projectSelect() {
this
.
withMergeRequestsEnabled
=
$
(
select
).
data
(
'
withMergeRequestsEnabled
'
);
this
.
allowClear
=
$
(
select
).
data
(
'
allowClear
'
)
||
false
;
placeholder
=
"
Search for project
"
;
placeholder
=
'
Search for project
'
;
if
(
this
.
includeGroups
)
{
placeholder
+=
"
or group
"
;
placeholder
+=
'
or group
'
;
}
$
(
select
).
select2
({
placeholder
:
placeholder
,
minimumInputLength
:
0
,
query
:
(
function
(
_this
)
{
return
function
(
query
)
{
query
:
(
function
(
_this
)
{
return
function
(
query
)
{
var
finalCallback
,
projectsCallback
;
finalCallback
=
function
(
projects
)
{
finalCallback
=
function
(
projects
)
{
var
data
;
data
=
{
results
:
projects
results
:
projects
,
};
return
query
.
callback
(
data
);
};
if
(
_this
.
includeGroups
)
{
projectsCallback
=
function
(
projects
)
{
projectsCallback
=
function
(
projects
)
{
var
groupsCallback
;
groupsCallback
=
function
(
groups
)
{
groupsCallback
=
function
(
groups
)
{
var
data
;
data
=
groups
.
concat
(
projects
);
return
finalCallback
(
data
);
...
...
@@ -48,17 +48,26 @@ export default function projectSelect() {
projectsCallback
=
finalCallback
;
}
if
(
_this
.
groupId
)
{
return
Api
.
groupProjects
(
_this
.
groupId
,
query
.
term
,
{
return
Api
.
groupProjects
(
_this
.
groupId
,
query
.
term
,
{
with_issues_enabled
:
_this
.
withIssuesEnabled
,
with_merge_requests_enabled
:
_this
.
withMergeRequestsEnabled
,
},
projectsCallback
);
},
projectsCallback
,
);
}
else
{
return
Api
.
projects
(
query
.
term
,
{
return
Api
.
projects
(
query
.
term
,
{
order_by
:
_this
.
orderBy
,
with_issues_enabled
:
_this
.
withIssuesEnabled
,
with_merge_requests_enabled
:
_this
.
withMergeRequestsEnabled
,
membership
:
!
_this
.
allProjects
,
},
projectsCallback
);
},
projectsCallback
,
);
}
};
})(
this
),
...
...
@@ -69,7 +78,7 @@ export default function projectSelect() {
url
:
project
.
web_url
,
});
},
text
:
function
(
project
)
{
text
:
function
(
project
)
{
return
project
.
name_with_namespace
||
project
.
name
;
},
...
...
@@ -79,7 +88,7 @@ export default function projectSelect() {
allowClear
:
this
.
allowClear
,
dropdownCssClass
:
"
ajax-project-dropdown
"
dropdownCssClass
:
'
ajax-project-dropdown
'
,
});
if
(
simpleFilter
)
return
select
;
return
new
ProjectSelectComboButton
(
select
);
...
...
app/assets/javascripts/project_select_combo_button.js
View file @
c559bcca
...
...
@@ -14,10 +14,11 @@ export default class ProjectSelectComboButton {
}
bindEvents
()
{
this
.
projectSelectInput
.
siblings
(
'
.new-project-item-select-button
'
)
this
.
projectSelectInput
.
siblings
(
'
.new-project-item-select-button
'
)
.
on
(
'
click
'
,
e
=>
this
.
openDropdown
(
e
));
this
.
newItemBtn
.
on
(
'
click
'
,
(
e
)
=>
{
this
.
newItemBtn
.
on
(
'
click
'
,
e
=>
{
if
(
!
this
.
getProjectFromLocalStorage
())
{
e
.
preventDefault
();
this
.
openDropdown
(
e
);
...
...
@@ -31,14 +32,21 @@ export default class ProjectSelectComboButton {
const
localStorageIsSafe
=
AccessorUtilities
.
isLocalStorageAccessSafe
();
if
(
localStorageIsSafe
)
{
this
.
localStorageKey
=
[
'
group
'
,
this
.
groupId
,
this
.
formattedText
.
localStorageItemType
,
'
recent-project
'
].
join
(
'
-
'
);
this
.
localStorageKey
=
[
'
group
'
,
this
.
groupId
,
this
.
formattedText
.
localStorageItemType
,
'
recent-project
'
,
].
join
(
'
-
'
);
this
.
setBtnTextFromLocalStorage
();
}
}
// eslint-disable-next-line class-methods-use-this
openDropdown
(
event
)
{
$
(
event
.
currentTarget
).
siblings
(
'
.project-item-select
'
).
select2
(
'
open
'
);
$
(
event
.
currentTarget
)
.
siblings
(
'
.project-item-select
'
)
.
select2
(
'
open
'
);
}
selectProject
()
{
...
...
@@ -86,8 +94,14 @@ export default class ProjectSelectComboButton {
const
defaultTextPrefix
=
this
.
resourceLabel
;
// the trailing slice call depluralizes each of these strings (e.g. new-issues -> new-issue)
const
localStorageItemType
=
`new-
${
this
.
resourceType
.
split
(
'
_
'
).
join
(
'
-
'
).
slice
(
0
,
-
1
)}
`
;
const
presetTextSuffix
=
this
.
resourceType
.
split
(
'
_
'
).
join
(
'
'
).
slice
(
0
,
-
1
);
const
localStorageItemType
=
`new-
${
this
.
resourceType
.
split
(
'
_
'
)
.
join
(
'
-
'
)
.
slice
(
0
,
-
1
)}
`
;
const
presetTextSuffix
=
this
.
resourceType
.
split
(
'
_
'
)
.
join
(
'
'
)
.
slice
(
0
,
-
1
);
return
{
localStorageItemType
,
// new-issue / new-merge-request
...
...
@@ -96,4 +110,3 @@ export default class ProjectSelectComboButton {
};
}
}
app/assets/javascripts/project_visibility.js
View file @
c559bcca
...
...
@@ -7,7 +7,7 @@ function setVisibilityOptions(namespaceSelector) {
const
selectedNamespace
=
namespaceSelector
.
options
[
namespaceSelector
.
selectedIndex
];
const
{
name
,
visibility
,
visibilityLevel
,
showPath
,
editPath
}
=
selectedNamespace
.
dataset
;
document
.
querySelectorAll
(
'
.visibility-level-setting .form-check
'
).
forEach
(
(
option
)
=>
{
document
.
querySelectorAll
(
'
.visibility-level-setting .form-check
'
).
forEach
(
option
=>
{
const
optionInput
=
option
.
querySelector
(
'
input[type=radio]
'
);
const
optionValue
=
optionInput
?
optionInput
.
value
:
0
;
const
optionTitle
=
option
.
querySelector
(
'
.option-title
'
);
...
...
@@ -20,8 +20,7 @@ function setVisibilityOptions(namespaceSelector) {
optionInput
.
disabled
=
true
;
const
reason
=
option
.
querySelector
(
'
.option-disabled-reason
'
);
if
(
reason
)
{
reason
.
innerHTML
=
`This project cannot be
${
optionName
}
because the visibility of
reason
.
innerHTML
=
`This project cannot be
${
optionName
}
because the visibility of
<a href="
${
showPath
}
">
${
name
}
</a> is
${
visibility
}
. To make this project
${
optionName
}
, you must first <a href="
${
editPath
}
">change the visibility</a>
of the parent group.`
;
...
...
app/assets/javascripts/prometheus_metrics/prometheus_metrics.js
View file @
c559bcca
...
...
@@ -65,10 +65,14 @@ export default class PrometheusMetrics {
let
totalMissingEnvVarMetrics
=
0
;
let
totalExporters
=
0
;
metrics
.
forEach
(
(
metric
)
=>
{
metrics
.
forEach
(
metric
=>
{
if
(
metric
.
active_metrics
>
0
)
{
totalExporters
+=
1
;
this
.
$monitoredMetricsList
.
append
(
`<li>
${
_
.
escape
(
metric
.
group
)}
<span class="badge">
${
_
.
escape
(
metric
.
active_metrics
)}
</span></li>`
);
this
.
$monitoredMetricsList
.
append
(
`<li>
${
_
.
escape
(
metric
.
group
)}
<span class="badge">
${
_
.
escape
(
metric
.
active_metrics
,
)}
</span></li>`
,
);
totalMonitoredMetrics
+=
metric
.
active_metrics
;
if
(
metric
.
metrics_missing_requirements
>
0
)
{
this
.
$missingEnvVarMetricsList
.
append
(
`<li>
${
_
.
escape
(
metric
.
group
)}
</li>`
);
...
...
@@ -78,17 +82,26 @@ export default class PrometheusMetrics {
});
if
(
totalMonitoredMetrics
===
0
)
{
const
emptyCommonMetricsText
=
sprintf
(
s__
(
'
PrometheusService|<p class="text-tertiary">No <a href="%{docsUrl}">common metrics</a> were found</p>
'
),
{
const
emptyCommonMetricsText
=
sprintf
(
s__
(
'
PrometheusService|<p class="text-tertiary">No <a href="%{docsUrl}">common metrics</a> were found</p>
'
,
),
{
docsUrl
:
this
.
helpMetricsPath
,
},
false
);
},
false
,
);
this
.
$monitoredMetricsEmpty
.
empty
();
this
.
$monitoredMetricsEmpty
.
append
(
emptyCommonMetricsText
);
this
.
showMonitoringMetricsPanelState
(
PANEL_STATE
.
EMPTY
);
}
else
{
const
metricsCountText
=
sprintf
(
s__
(
'
PrometheusService|%{exporters} with %{metrics} were found
'
),
{
const
metricsCountText
=
sprintf
(
s__
(
'
PrometheusService|%{exporters} with %{metrics} were found
'
),
{
exporters
:
n__
(
'
%d exporter
'
,
'
%d exporters
'
,
totalExporters
),
metrics
:
n__
(
'
%d metric
'
,
'
%d metrics
'
,
totalMonitoredMetrics
),
});
},
);
this
.
$monitoredMetricsCount
.
text
(
metricsCountText
);
this
.
showMonitoringMetricsPanelState
(
PANEL_STATE
.
LIST
);
...
...
@@ -102,7 +115,8 @@ export default class PrometheusMetrics {
loadActiveMetrics
()
{
this
.
showMonitoringMetricsPanelState
(
PANEL_STATE
.
LOADING
);
backOff
((
next
,
stop
)
=>
{
axios
.
get
(
this
.
activeMetricsEndpoint
)
axios
.
get
(
this
.
activeMetricsEndpoint
)
.
then
(({
data
})
=>
{
if
(
data
&&
data
.
success
)
{
stop
(
data
);
...
...
@@ -117,7 +131,7 @@ export default class PrometheusMetrics {
})
.
catch
(
stop
);
})
.
then
(
(
res
)
=>
{
.
then
(
res
=>
{
if
(
res
&&
res
.
data
&&
res
.
data
.
length
)
{
this
.
populateActiveMetrics
(
res
.
data
);
}
else
{
...
...
app/assets/javascripts/raven/raven_config.js
View file @
c559bcca
...
...
@@ -9,7 +9,7 @@ const IGNORE_ERRORS = [
'
canvas.contentDocument
'
,
'
MyApp_RemoveAllHighlights
'
,
'
http://tt.epicplay.com
'
,
'
Can
\'
t find variable: ZiteReader
'
,
"
Can't find variable: ZiteReader
"
,
'
jigsaw is not defined
'
,
'
ComboSearch is not defined
'
,
'
http://loading.retry.widdit.com/
'
,
...
...
app/assets/javascripts/ref_select_dropdown.js
View file @
c559bcca
...
...
@@ -2,7 +2,8 @@ import $ from 'jquery';
class
RefSelectDropdown
{
constructor
(
$dropdownButton
,
availableRefs
)
{
const
availableRefsValue
=
availableRefs
||
JSON
.
parse
(
document
.
getElementById
(
'
availableRefs
'
).
innerHTML
);
const
availableRefsValue
=
availableRefs
||
JSON
.
parse
(
document
.
getElementById
(
'
availableRefs
'
).
innerHTML
);
$dropdownButton
.
glDropdown
({
data
:
availableRefsValue
,
filterable
:
true
,
...
...
@@ -29,7 +30,7 @@ class RefSelectDropdown {
const
$fieldInput
=
$
(
`input[name="
${
$dropdownButton
.
data
(
'
fieldName
'
)}
"]`
,
$dropdownContainer
);
const
$filterInput
=
$
(
'
input[type="search"]
'
,
$dropdownContainer
);
$filterInput
.
on
(
'
keyup
'
,
(
e
)
=>
{
$filterInput
.
on
(
'
keyup
'
,
e
=>
{
const
keyCode
=
e
.
keyCode
||
e
.
which
;
if
(
keyCode
!==
13
)
return
;
...
...
app/assets/javascripts/settings_panels.js
View file @
c559bcca
...
...
@@ -3,10 +3,14 @@ import { __ } from './locale';
function
expandSection
(
$section
)
{
$section
.
find
(
'
.js-settings-toggle:not(.js-settings-toggle-trigger-only)
'
).
text
(
__
(
'
Collapse
'
));
$section
.
find
(
'
.settings-content
'
).
off
(
'
scroll.expandSection
'
).
scrollTop
(
0
);
$section
.
find
(
'
.settings-content
'
)
.
off
(
'
scroll.expandSection
'
)
.
scrollTop
(
0
);
$section
.
addClass
(
'
expanded
'
);
if
(
!
$section
.
hasClass
(
'
no-animate
'
))
{
$section
.
addClass
(
'
animating
'
)
$section
.
addClass
(
'
animating
'
)
.
one
(
'
animationend.animateSection
'
,
()
=>
$section
.
removeClass
(
'
animating
'
));
}
}
...
...
@@ -16,7 +20,8 @@ function closeSection($section) {
$section
.
find
(
'
.settings-content
'
).
on
(
'
scroll.expandSection
'
,
()
=>
expandSection
(
$section
));
$section
.
removeClass
(
'
expanded
'
);
if
(
!
$section
.
hasClass
(
'
no-animate
'
))
{
$section
.
addClass
(
'
animating
'
)
$section
.
addClass
(
'
animating
'
)
.
one
(
'
animationend.animateSection
'
,
()
=>
$section
.
removeClass
(
'
animating
'
));
}
}
...
...
app/assets/javascripts/single_file_diff.js
View file @
c559bcca
...
...
@@ -10,8 +10,10 @@ import syntaxHighlight from './syntax_highlight';
const
WRAPPER
=
'
<div class="diff-content"></div>
'
;
const
LOADING_HTML
=
'
<i class="fa fa-spinner fa-spin"></i>
'
;
const
ERROR_HTML
=
'
<div class="nothing-here-block"><i class="fa fa-warning"></i> Could not load diff</div>
'
;
const
COLLAPSED_HTML
=
'
<div class="nothing-here-block diff-collapsed">This diff is collapsed. <button class="click-to-expand btn btn-link">Click to expand it.</button></div>
'
;
const
ERROR_HTML
=
'
<div class="nothing-here-block"><i class="fa fa-warning"></i> Could not load diff</div>
'
;
const
COLLAPSED_HTML
=
'
<div class="nothing-here-block diff-collapsed">This diff is collapsed. <button class="click-to-expand btn btn-link">Click to expand it.</button></div>
'
;
export
default
class
SingleFileDiff
{
constructor
(
file
)
{
...
...
@@ -23,23 +25,36 @@ export default class SingleFileDiff {
this
.
isOpen
=
!
this
.
diffForPath
;
if
(
this
.
diffForPath
)
{
this
.
collapsedContent
=
this
.
content
;
this
.
loadingContent
=
$
(
WRAPPER
).
addClass
(
'
loading
'
).
html
(
LOADING_HTML
).
hide
();
this
.
loadingContent
=
$
(
WRAPPER
)
.
addClass
(
'
loading
'
)
.
html
(
LOADING_HTML
)
.
hide
();
this
.
content
=
null
;
this
.
collapsedContent
.
after
(
this
.
loadingContent
);
this
.
$toggleIcon
.
addClass
(
'
fa-caret-right
'
);
}
else
{
this
.
collapsedContent
=
$
(
WRAPPER
).
html
(
COLLAPSED_HTML
).
hide
();
this
.
collapsedContent
=
$
(
WRAPPER
)
.
html
(
COLLAPSED_HTML
)
.
hide
();
this
.
content
.
after
(
this
.
collapsedContent
);
this
.
$toggleIcon
.
addClass
(
'
fa-caret-down
'
);
}
$
(
'
.js-file-title, .click-to-expand
'
,
this
.
file
).
on
(
'
click
'
,
(
function
(
e
)
{
$
(
'
.js-file-title, .click-to-expand
'
,
this
.
file
).
on
(
'
click
'
,
function
(
e
)
{
this
.
toggleDiff
(
$
(
e
.
target
));
}).
bind
(
this
));
}.
bind
(
this
),
);
}
toggleDiff
(
$target
,
cb
)
{
if
(
!
$target
.
hasClass
(
'
js-file-title
'
)
&&
!
$target
.
hasClass
(
'
click-to-expand
'
)
&&
!
$target
.
hasClass
(
'
diff-toggle-caret
'
))
return
;
if
(
!
$target
.
hasClass
(
'
js-file-title
'
)
&&
!
$target
.
hasClass
(
'
click-to-expand
'
)
&&
!
$target
.
hasClass
(
'
diff-toggle-caret
'
)
)
return
;
this
.
isOpen
=
!
this
.
isOpen
;
if
(
!
this
.
isOpen
&&
!
this
.
hasError
)
{
this
.
content
.
hide
();
...
...
@@ -65,7 +80,8 @@ export default class SingleFileDiff {
this
.
collapsedContent
.
hide
();
this
.
loadingContent
.
show
();
axios
.
get
(
this
.
diffForPath
)
axios
.
get
(
this
.
diffForPath
)
.
then
(({
data
})
=>
{
this
.
loadingContent
.
hide
();
if
(
data
.
html
)
{
...
...
app/assets/javascripts/smart_interval.js
View file @
c559bcca
...
...
@@ -93,7 +93,9 @@ export default class SmartInterval {
destroy
()
{
this
.
cancel
();
document
.
removeEventListener
(
'
visibilitychange
'
,
this
.
handleVisibilityChange
);
$
(
document
).
off
(
'
visibilitychange
'
).
off
(
'
beforeunload
'
);
$
(
document
)
.
off
(
'
visibilitychange
'
)
.
off
(
'
beforeunload
'
);
}
/* private */
...
...
@@ -111,11 +113,12 @@ export default class SmartInterval {
triggerCallback
()
{
this
.
isLoading
=
true
;
this
.
cfg
.
callback
()
this
.
cfg
.
callback
()
.
then
(()
=>
{
this
.
isLoading
=
false
;
})
.
catch
(
(
err
)
=>
{
.
catch
(
err
=>
{
this
.
isLoading
=
false
;
throw
err
;
});
...
...
@@ -134,9 +137,9 @@ export default class SmartInterval {
handleVisibilityChange
(
e
)
{
this
.
state
.
pageVisibility
=
e
.
target
.
visibilityState
;
const
intervalAction
=
this
.
isPageVisible
()
?
this
.
onVisibilityVisible
:
this
.
onVisibilityHidden
;
const
intervalAction
=
this
.
isPageVisible
()
?
this
.
onVisibilityVisible
:
this
.
onVisibilityHidden
;
intervalAction
.
apply
(
this
);
}
...
...
@@ -162,7 +165,9 @@ export default class SmartInterval {
this
.
setCurrentInterval
(
nextInterval
);
}
isPageVisible
()
{
return
this
.
state
.
pageVisibility
===
'
visible
'
;
}
isPageVisible
()
{
return
this
.
state
.
pageVisibility
===
'
visible
'
;
}
stopTimer
()
{
const
{
state
}
=
this
;
...
...
@@ -170,4 +175,3 @@ export default class SmartInterval {
state
.
intervalId
=
window
.
clearInterval
(
state
.
intervalId
);
}
}
app/assets/javascripts/star.js
View file @
c559bcca
...
...
@@ -11,10 +11,14 @@ export default class Star {
const
$starSpan
=
$this
.
find
(
'
span
'
);
const
$startIcon
=
$this
.
find
(
'
svg
'
);
axios
.
post
(
$this
.
data
(
'
endpoint
'
))
axios
.
post
(
$this
.
data
(
'
endpoint
'
))
.
then
(({
data
})
=>
{
const
isStarred
=
$starSpan
.
hasClass
(
'
starred
'
);
$this
.
parent
().
find
(
'
.star-count
'
).
text
(
data
.
star_count
);
$this
.
parent
()
.
find
(
'
.star-count
'
)
.
text
(
data
.
star_count
);
if
(
isStarred
)
{
$starSpan
.
removeClass
(
'
starred
'
).
text
(
s__
(
'
StarProject|Star
'
));
...
...
app/assets/javascripts/task_list.js
View file @
c559bcca
...
...
@@ -26,7 +26,11 @@ export default class TaskList {
// Prevent duplicate event bindings
this
.
disable
();
$
(
`
${
this
.
selector
}
.js-task-list-container`
).
taskList
(
'
enable
'
);
$
(
document
).
on
(
'
tasklist:changed
'
,
`
${
this
.
selector
}
.js-task-list-container`
,
this
.
update
.
bind
(
this
));
$
(
document
).
on
(
'
tasklist:changed
'
,
`
${
this
.
selector
}
.js-task-list-container`
,
this
.
update
.
bind
(
this
),
);
}
disable
()
{
...
...
@@ -41,7 +45,8 @@ export default class TaskList {
[
this
.
fieldName
]:
$target
.
val
(),
};
return
axios
.
patch
(
$target
.
data
(
'
updateUrl
'
)
||
$
(
'
form.js-issuable-update
'
).
attr
(
'
action
'
),
patchData
)
return
axios
.
patch
(
$target
.
data
(
'
updateUrl
'
)
||
$
(
'
form.js-issuable-update
'
).
attr
(
'
action
'
),
patchData
)
.
then
(({
data
})
=>
this
.
onSuccess
(
data
))
.
catch
(
err
=>
this
.
onError
(
err
));
}
...
...
app/assets/javascripts/templates/issuable_template_selector.js
View file @
c559bcca
...
...
@@ -31,12 +31,18 @@ export default class IssuableTemplateSelector extends TemplateSelector {
requestFile
(
query
)
{
this
.
startLoadingSpinner
();
Api
.
issueTemplate
(
this
.
namespacePath
,
this
.
projectPath
,
query
.
name
,
this
.
issuableType
,
(
err
,
currentTemplate
)
=>
{
Api
.
issueTemplate
(
this
.
namespacePath
,
this
.
projectPath
,
query
.
name
,
this
.
issuableType
,
(
err
,
currentTemplate
)
=>
{
this
.
currentTemplate
=
currentTemplate
;
this
.
stopLoadingSpinner
();
if
(
err
)
return
;
// Error handled by global AJAX error handler
this
.
setInputValueToTemplateContent
();
});
},
);
return
;
}
...
...
app/assets/javascripts/terminal/terminal.js
View file @
c559bcca
...
...
@@ -4,10 +4,14 @@ import * as fit from 'xterm/lib/addons/fit/fit';
export
default
class
GLTerminal
{
constructor
(
options
=
{})
{
this
.
options
=
Object
.
assign
({},
{
this
.
options
=
Object
.
assign
(
{},
{
cursorBlink
:
true
,
screenKeys
:
true
,
},
options
);
},
options
,
);
this
.
container
=
document
.
querySelector
(
options
.
selector
);
...
...
app/assets/javascripts/test_utils/simulate_drag.js
View file @
c559bcca
...
...
@@ -4,15 +4,43 @@ function simulateEvent(el, type, options = {}) {
if
(
/^mouse/
.
test
(
type
))
{
event
=
el
.
ownerDocument
.
createEvent
(
'
MouseEvents
'
);
event
.
initMouseEvent
(
type
,
true
,
true
,
el
.
ownerDocument
.
defaultView
,
options
.
button
,
options
.
screenX
,
options
.
screenY
,
options
.
clientX
,
options
.
clientY
,
options
.
ctrlKey
,
options
.
altKey
,
options
.
shiftKey
,
options
.
metaKey
,
options
.
button
,
el
);
event
.
initMouseEvent
(
type
,
true
,
true
,
el
.
ownerDocument
.
defaultView
,
options
.
button
,
options
.
screenX
,
options
.
screenY
,
options
.
clientX
,
options
.
clientY
,
options
.
ctrlKey
,
options
.
altKey
,
options
.
shiftKey
,
options
.
metaKey
,
options
.
button
,
el
,
);
}
else
{
event
=
el
.
ownerDocument
.
createEvent
(
'
CustomEvent
'
);
event
.
initCustomEvent
(
type
,
true
,
true
,
el
.
ownerDocument
.
defaultView
,
options
.
button
,
options
.
screenX
,
options
.
screenY
,
options
.
clientX
,
options
.
clientY
,
options
.
ctrlKey
,
options
.
altKey
,
options
.
shiftKey
,
options
.
metaKey
,
options
.
button
,
el
);
event
.
initCustomEvent
(
type
,
true
,
true
,
el
.
ownerDocument
.
defaultView
,
options
.
button
,
options
.
screenX
,
options
.
screenY
,
options
.
clientX
,
options
.
clientY
,
options
.
ctrlKey
,
options
.
altKey
,
options
.
shiftKey
,
options
.
metaKey
,
options
.
button
,
el
,
);
event
.
dataTransfer
=
{
data
:
{},
...
...
@@ -37,14 +65,16 @@ function simulateEvent(el, type, options = {}) {
}
function
isLast
(
target
)
{
const
el
=
typeof
target
.
el
===
'
string
'
?
document
.
getElementById
(
target
.
el
.
substr
(
1
))
:
target
.
el
;
const
el
=
typeof
target
.
el
===
'
string
'
?
document
.
getElementById
(
target
.
el
.
substr
(
1
))
:
target
.
el
;
const
{
children
}
=
el
;
return
children
.
length
-
1
===
target
.
index
;
}
function
getTarget
(
target
)
{
const
el
=
typeof
target
.
el
===
'
string
'
?
document
.
getElementById
(
target
.
el
.
substr
(
1
))
:
target
.
el
;
const
el
=
typeof
target
.
el
===
'
string
'
?
document
.
getElementById
(
target
.
el
.
substr
(
1
))
:
target
.
el
;
const
{
children
}
=
el
;
return
(
...
...
@@ -58,13 +88,13 @@ function getTarget(target) {
function
getRect
(
el
)
{
const
rect
=
el
.
getBoundingClientRect
();
const
width
=
rect
.
right
-
rect
.
left
;
const
height
=
(
rect
.
bottom
-
rect
.
top
)
+
10
;
const
height
=
rect
.
bottom
-
rect
.
top
+
10
;
return
{
x
:
rect
.
left
,
y
:
rect
.
top
,
cx
:
rect
.
left
+
(
width
/
2
)
,
cy
:
rect
.
top
+
(
height
/
2
)
,
cx
:
rect
.
left
+
width
/
2
,
cy
:
rect
.
top
+
height
/
2
,
w
:
width
,
h
:
height
,
hw
:
width
/
2
,
...
...
@@ -112,8 +142,8 @@ export default function simulateDrag(options) {
const
dragInterval
=
setInterval
(()
=>
{
const
progress
=
(
new
Date
().
getTime
()
-
startTime
)
/
duration
;
const
x
=
(
fromRect
.
cx
+
((
toRect
.
cx
-
fromRect
.
cx
)
*
progress
))
;
const
y
=
(
fromRect
.
cy
+
((
toRect
.
cy
-
fromRect
.
cy
)
*
progress
))
;
const
x
=
fromRect
.
cx
+
(
toRect
.
cx
-
fromRect
.
cx
)
*
progress
;
const
y
=
fromRect
.
cy
+
(
toRect
.
cy
-
fromRect
.
cy
)
*
progress
;
const
overEl
=
fromEl
.
ownerDocument
.
elementFromPoint
(
x
,
y
);
simulateEvent
(
overEl
,
'
mousemove
'
,
{
...
...
app/assets/javascripts/test_utils/simulate_input.js
View file @
c559bcca
...
...
@@ -12,7 +12,7 @@ export default function simulateInput(target, text) {
}
if
(
text
.
length
>
0
)
{
Array
.
prototype
.
forEach
.
call
(
text
,
(
char
)
=>
{
Array
.
prototype
.
forEach
.
call
(
text
,
char
=>
{
input
.
value
+=
char
;
triggerEvents
(
input
);
});
...
...
app/assets/javascripts/toggle_buttons.js
View file @
c559bcca
...
...
@@ -49,7 +49,7 @@ function onToggleClicked(toggle, input, clickCallback) {
export
default
function
setupToggleButtons
(
container
,
clickCallback
=
()
=>
{})
{
const
toggles
=
container
.
querySelectorAll
(
'
.js-project-feature-toggle
'
);
toggles
.
forEach
(
(
toggle
)
=>
{
toggles
.
forEach
(
toggle
=>
{
const
input
=
toggle
.
querySelector
(
'
.js-project-feature-toggle-input
'
);
const
isOn
=
convertPermissionToBoolean
(
input
.
value
);
...
...
app/assets/javascripts/tree.js
View file @
c559bcca
...
...
@@ -8,7 +8,7 @@ export default class TreeView {
this
.
initKeyNav
();
// Code browser tree slider
// Make the entire tree-item row clickable, but not if clicking another link (like a commit message)
$
(
"
.tree-content-holder .tree-item
"
).
on
(
'
click
'
,
function
(
e
)
{
$
(
'
.tree-content-holder .tree-item
'
).
on
(
'
click
'
,
function
(
e
)
{
var
$clickedEl
,
path
;
$clickedEl
=
$
(
e
.
target
);
path
=
$
(
'
.tree-item-file-name a
'
,
this
).
attr
(
'
href
'
);
...
...
@@ -27,33 +27,33 @@ export default class TreeView {
initKeyNav
()
{
var
li
,
liSelected
;
li
=
$
(
"
tr.tree-item
"
);
li
=
$
(
'
tr.tree-item
'
);
liSelected
=
null
;
return
$
(
'
body
'
).
keydown
(
function
(
e
)
{
var
next
,
path
;
if
(
$
(
"
input:focus
"
).
length
>
0
&&
(
e
.
which
===
38
||
e
.
which
===
40
))
{
if
(
$
(
'
input:focus
'
).
length
>
0
&&
(
e
.
which
===
38
||
e
.
which
===
40
))
{
return
false
;
}
if
(
e
.
which
===
40
)
{
if
(
liSelected
)
{
next
=
liSelected
.
next
();
if
(
next
.
length
>
0
)
{
liSelected
.
removeClass
(
"
selected
"
);
liSelected
=
next
.
addClass
(
"
selected
"
);
liSelected
.
removeClass
(
'
selected
'
);
liSelected
=
next
.
addClass
(
'
selected
'
);
}
}
else
{
liSelected
=
li
.
eq
(
0
).
addClass
(
"
selected
"
);
liSelected
=
li
.
eq
(
0
).
addClass
(
'
selected
'
);
}
return
$
(
liSelected
).
focus
();
}
else
if
(
e
.
which
===
38
)
{
if
(
liSelected
)
{
next
=
liSelected
.
prev
();
if
(
next
.
length
>
0
)
{
liSelected
.
removeClass
(
"
selected
"
);
liSelected
=
next
.
addClass
(
"
selected
"
);
liSelected
.
removeClass
(
'
selected
'
);
liSelected
=
next
.
addClass
(
'
selected
'
);
}
}
else
{
liSelected
=
li
.
last
().
addClass
(
"
selected
"
);
liSelected
=
li
.
last
().
addClass
(
'
selected
'
);
}
return
$
(
liSelected
).
focus
();
}
else
if
(
e
.
which
===
13
)
{
...
...
app/assets/javascripts/u2f/authenticate.js
View file @
c559bcca
...
...
@@ -49,7 +49,7 @@ export default class U2FAuthenticate {
start
()
{
return
importU2FLibrary
()
.
then
(
(
utils
)
=>
{
.
then
(
utils
=>
{
this
.
u2fUtils
=
utils
;
this
.
renderInProgress
();
})
...
...
@@ -57,14 +57,19 @@ export default class U2FAuthenticate {
}
authenticate
()
{
return
this
.
u2fUtils
.
sign
(
this
.
appId
,
this
.
challenge
,
this
.
signRequests
,
(
response
)
=>
{
return
this
.
u2fUtils
.
sign
(
this
.
appId
,
this
.
challenge
,
this
.
signRequests
,
response
=>
{
if
(
response
.
errorCode
)
{
const
error
=
new
U2FError
(
response
.
errorCode
,
'
authenticate
'
);
return
this
.
renderError
(
error
);
}
return
this
.
renderAuthenticated
(
JSON
.
stringify
(
response
));
},
10
);
},
10
,
);
}
renderTemplate
(
name
,
params
)
{
...
...
@@ -99,5 +104,4 @@ export default class U2FAuthenticate {
this
.
container
[
0
].
classList
.
add
(
'
hidden
'
);
this
.
fallbackUI
.
classList
.
remove
(
'
hidden
'
);
}
}
app/assets/javascripts/u2f/register.js
View file @
c559bcca
...
...
@@ -34,7 +34,7 @@ export default class U2FRegister {
start
()
{
return
importU2FLibrary
()
.
then
(
(
utils
)
=>
{
.
then
(
utils
=>
{
this
.
u2fUtils
=
utils
;
this
.
renderSetup
();
})
...
...
@@ -42,14 +42,19 @@ export default class U2FRegister {
}
register
()
{
return
this
.
u2fUtils
.
register
(
this
.
appId
,
this
.
registerRequests
,
this
.
signRequests
,
(
response
)
=>
{
return
this
.
u2fUtils
.
register
(
this
.
appId
,
this
.
registerRequests
,
this
.
signRequests
,
response
=>
{
if
(
response
.
errorCode
)
{
const
error
=
new
U2FError
(
response
.
errorCode
,
'
register
'
);
return
this
.
renderError
(
error
);
}
return
this
.
renderRegistered
(
JSON
.
stringify
(
response
));
},
10
);
},
10
,
);
}
renderTemplate
(
name
,
params
)
{
...
...
app/assets/javascripts/u2f/util.js
View file @
c559bcca
...
...
@@ -19,11 +19,10 @@ function getChromeVersion(userAgent) {
export
function
canInjectU2fApi
(
userAgent
)
{
const
isSupportedChrome
=
isChrome
(
userAgent
)
&&
getChromeVersion
(
userAgent
)
>=
41
;
const
isSupportedOpera
=
isOpera
(
userAgent
)
&&
getOperaVersion
(
userAgent
)
>=
40
;
const
isMobile
=
(
const
isMobile
=
userAgent
.
indexOf
(
'
droid
'
)
>=
0
||
userAgent
.
indexOf
(
'
CriOS
'
)
>=
0
||
/
\b(
iPad|iPhone|iPod
)(?=
;
)
/
.
test
(
userAgent
)
);
/
\b(
iPad|iPhone|iPod
)(?=
;
)
/
.
test
(
userAgent
);
return
(
isSupportedChrome
||
isSupportedOpera
)
&&
!
isMobile
;
}
...
...
app/assets/javascripts/ui_development_kit.js
View file @
c559bcca
...
...
@@ -4,13 +4,17 @@ import Api from './api';
export
default
()
=>
{
$
(
'
#js-project-dropdown
'
).
glDropdown
({
data
:
(
term
,
callback
)
=>
{
Api
.
projects
(
term
,
{
Api
.
projects
(
term
,
{
order_by
:
'
last_activity_at
'
,
},
(
data
)
=>
{
},
data
=>
{
callback
(
data
);
});
},
text
:
project
=>
(
project
.
name_with_namespace
||
project
.
name
),
);
},
text
:
project
=>
project
.
name_with_namespace
||
project
.
name
,
selectable
:
true
,
fieldName
:
'
author_id
'
,
filterable
:
true
,
...
...
@@ -18,6 +22,6 @@ export default () => {
fields
:
[
'
name_with_namespace
'
],
},
id
:
data
=>
data
.
id
,
isSelected
:
data
=>
(
data
.
id
===
2
)
,
isSelected
:
data
=>
data
.
id
===
2
,
});
};
app/assets/javascripts/usage_ping_consent.js
View file @
c559bcca
...
...
@@ -4,7 +4,7 @@ import Flash, { hideFlash } from './flash';
import
{
convertPermissionToBoolean
}
from
'
./lib/utils/common_utils
'
;
export
default
()
=>
{
$
(
'
body
'
).
on
(
'
click
'
,
'
.js-usage-consent-action
'
,
(
e
)
=>
{
$
(
'
body
'
).
on
(
'
click
'
,
'
.js-usage-consent-action
'
,
e
=>
{
e
.
preventDefault
();
e
.
stopImmediatePropagation
();
// overwrite rails listener
...
...
@@ -18,7 +18,8 @@ export default () => {
const
hideConsentMessage
=
()
=>
hideFlash
(
document
.
querySelector
(
'
.ping-consent-message
'
));
axios
.
put
(
url
,
data
)
axios
.
put
(
url
,
data
)
.
then
(()
=>
{
hideConsentMessage
();
})
...
...
app/assets/javascripts/users_select.js
View file @
c559bcca
...
...
@@ -15,8 +15,8 @@ function UsersSelect(currentUser, els, options = {}) {
var
$els
;
this
.
users
=
this
.
users
.
bind
(
this
);
this
.
user
=
this
.
user
.
bind
(
this
);
this
.
usersPath
=
"
/autocomplete/users.json
"
;
this
.
userPath
=
"
/autocomplete/users/:id.json
"
;
this
.
usersPath
=
'
/autocomplete/users.json
'
;
this
.
userPath
=
'
/autocomplete/users/:id.json
'
;
if
(
currentUser
!=
null
)
{
if
(
typeof
currentUser
===
'
object
'
)
{
this
.
currentUser
=
currentUser
;
...
...
@@ -33,10 +33,29 @@ function UsersSelect(currentUser, els, options = {}) {
$els
=
$
(
'
.js-user-search
'
);
}
$els
.
each
((
function
(
_this
)
{
$els
.
each
(
(
function
(
_this
)
{
return
function
(
i
,
dropdown
)
{
var
options
=
{};
var
$block
,
$collapsedSidebar
,
$dropdown
,
$loading
,
$selectbox
,
$value
,
abilityName
,
assignTo
,
assigneeTemplate
,
collapsedAssigneeTemplate
,
defaultLabel
,
defaultNullUser
,
firstUser
,
issueURL
,
selectedId
,
selectedIdDefault
,
showAnyUser
,
showNullUser
,
showMenuAbove
;
var
$block
,
$collapsedSidebar
,
$dropdown
,
$loading
,
$selectbox
,
$value
,
abilityName
,
assignTo
,
assigneeTemplate
,
collapsedAssigneeTemplate
,
defaultLabel
,
defaultNullUser
,
firstUser
,
issueURL
,
selectedId
,
selectedIdDefault
,
showAnyUser
,
showNullUser
,
showMenuAbove
;
$dropdown
=
$
(
dropdown
);
options
.
projectId
=
$dropdown
.
data
(
'
projectId
'
);
options
.
groupId
=
$dropdown
.
data
(
'
groupId
'
);
...
...
@@ -57,15 +76,16 @@ function UsersSelect(currentUser, els, options = {}) {
$value
=
$block
.
find
(
'
.value
'
);
$collapsedSidebar
=
$block
.
find
(
'
.sidebar-collapsed-user
'
);
$loading
=
$block
.
find
(
'
.block-loading
'
).
fadeOut
();
selectedIdDefault
=
(
defaultNullUser
&&
showNullUser
)
?
0
:
null
;
selectedIdDefault
=
defaultNullUser
&&
showNullUser
?
0
:
null
;
selectedId
=
$dropdown
.
data
(
'
selected
'
);
if
(
selectedId
===
undefined
)
{
selectedId
=
selectedIdDefault
;
}
const
assignYourself
=
function
()
{
const
unassignedSelected
=
$dropdown
.
closest
(
'
.selectbox
'
)
const
assignYourself
=
function
()
{
const
unassignedSelected
=
$dropdown
.
closest
(
'
.selectbox
'
)
.
find
(
`input[name='
${
$dropdown
.
data
(
'
fieldName
'
)}
'][value=0]`
);
if
(
unassignedSelected
)
{
...
...
@@ -98,8 +118,7 @@ function UsersSelect(currentUser, els, options = {}) {
}
const
getSelectedUserInputs
=
function
()
{
return
$selectbox
.
find
(
`input[name="
${
$dropdown
.
data
(
'
fieldName
'
)}
"]`
);
return
$selectbox
.
find
(
`input[name="
${
$dropdown
.
data
(
'
fieldName
'
)}
"]`
);
};
const
getSelected
=
function
()
{
...
...
@@ -115,7 +134,8 @@ function UsersSelect(currentUser, els, options = {}) {
if
(
selected
.
length
>
maxSelect
)
{
const
firstSelectedId
=
selected
[
0
];
const
firstSelected
=
$dropdown
.
closest
(
'
.selectbox
'
)
const
firstSelected
=
$dropdown
.
closest
(
'
.selectbox
'
)
.
find
(
`input[name='
${
$dropdown
.
data
(
'
fieldName
'
)}
'][value=
${
firstSelectedId
}
]`
);
firstSelected
.
remove
();
...
...
@@ -127,8 +147,7 @@ function UsersSelect(currentUser, els, options = {}) {
};
const
getMultiSelectDropdownTitle
=
function
(
selectedUser
,
isSelected
)
{
const
selectedUsers
=
getSelected
()
.
filter
(
u
=>
u
!==
0
);
const
selectedUsers
=
getSelected
().
filter
(
u
=>
u
!==
0
);
const
firstUser
=
getSelectedUserInputs
()
.
map
((
index
,
input
)
=>
({
...
...
@@ -150,7 +169,7 @@ function UsersSelect(currentUser, els, options = {}) {
}
};
$
(
'
.assign-to-me-link
'
).
on
(
'
click
'
,
(
e
)
=>
{
$
(
'
.assign-to-me-link
'
).
on
(
'
click
'
,
e
=>
{
e
.
preventDefault
();
$
(
e
.
currentTarget
).
hide
();
...
...
@@ -159,16 +178,22 @@ function UsersSelect(currentUser, els, options = {}) {
checkMaxSelect
();
const
currentUserInfo
=
$dropdown
.
data
(
'
currentUserInfo
'
);
$dropdown
.
find
(
'
.dropdown-toggle-text
'
).
text
(
getMultiSelectDropdownTitle
(
currentUserInfo
)).
removeClass
(
'
is-default
'
);
$dropdown
.
find
(
'
.dropdown-toggle-text
'
)
.
text
(
getMultiSelectDropdownTitle
(
currentUserInfo
))
.
removeClass
(
'
is-default
'
);
}
else
{
const
$input
=
$
(
`input[name="
${
$dropdown
.
data
(
'
fieldName
'
)}
"]`
);
$input
.
val
(
gon
.
current_user_id
);
selectedId
=
$input
.
val
();
$dropdown
.
find
(
'
.dropdown-toggle-text
'
).
text
(
gon
.
current_user_fullname
).
removeClass
(
'
is-default
'
);
$dropdown
.
find
(
'
.dropdown-toggle-text
'
)
.
text
(
gon
.
current_user_fullname
)
.
removeClass
(
'
is-default
'
);
}
});
$block
.
on
(
'
click
'
,
'
.js-assign-yourself
'
,
(
e
)
=>
{
$block
.
on
(
'
click
'
,
'
.js-assign-yourself
'
,
e
=>
{
e
.
preventDefault
();
return
assignTo
(
_this
.
currentUser
.
id
);
});
...
...
@@ -181,8 +206,7 @@ function UsersSelect(currentUser, els, options = {}) {
$loading
.
removeClass
(
'
hidden
'
).
fadeIn
();
$dropdown
.
trigger
(
'
loading.gl.dropdown
'
);
return
axios
.
put
(
issueURL
,
data
)
.
then
(({
data
})
=>
{
return
axios
.
put
(
issueURL
,
data
).
then
(({
data
})
=>
{
var
user
,
tooltipTitle
;
$dropdown
.
trigger
(
'
loaded.gl.dropdown
'
);
$loading
.
fadeOut
();
...
...
@@ -190,14 +214,14 @@ function UsersSelect(currentUser, els, options = {}) {
user
=
{
name
:
data
.
assignee
.
name
,
username
:
data
.
assignee
.
username
,
avatar
:
data
.
assignee
.
avatar_url
avatar
:
data
.
assignee
.
avatar_url
,
};
tooltipTitle
=
_
.
escape
(
user
.
name
);
}
else
{
user
=
{
name
:
'
Unassigned
'
,
username
:
''
,
avatar
:
''
avatar
:
''
,
};
tooltipTitle
=
__
(
'
Assignee
'
);
}
...
...
@@ -206,17 +230,25 @@ function UsersSelect(currentUser, els, options = {}) {
return
$collapsedSidebar
.
html
(
collapsedAssigneeTemplate
(
user
));
});
};
collapsedAssigneeTemplate
=
_
.
template
(
'
<% if( avatar ) { %> <a class="author-link" href="/<%- username %>"> <img width="24" class="avatar avatar-inline s24" alt="" src="<%- avatar %>"> </a> <% } else { %> <i class="fa fa-user"></i> <% } %>
'
);
assigneeTemplate
=
_
.
template
(
'
<% if (username) { %> <a class="author-link bold" href="/<%- username %>"> <% if( avatar ) { %> <img width="32" class="avatar avatar-inline s32" alt="" src="<%- avatar %>"> <% } %> <span class="author"><%- name %></span> <span class="username"> @<%- username %> </span> </a> <% } else { %> <span class="no-value assign-yourself"> No assignee - <a href="#" class="js-assign-yourself"> assign yourself </a> </span> <% } %>
'
);
collapsedAssigneeTemplate
=
_
.
template
(
'
<% if( avatar ) { %> <a class="author-link" href="/<%- username %>"> <img width="24" class="avatar avatar-inline s24" alt="" src="<%- avatar %>"> </a> <% } else { %> <i class="fa fa-user"></i> <% } %>
'
,
);
assigneeTemplate
=
_
.
template
(
'
<% if (username) { %> <a class="author-link bold" href="/<%- username %>"> <% if( avatar ) { %> <img width="32" class="avatar avatar-inline s32" alt="" src="<%- avatar %>"> <% } %> <span class="author"><%- name %></span> <span class="username"> @<%- username %> </span> </a> <% } else { %> <span class="no-value assign-yourself"> No assignee - <a href="#" class="js-assign-yourself"> assign yourself </a> </span> <% } %>
'
,
);
return
$dropdown
.
glDropdown
({
showMenuAbove
:
showMenuAbove
,
data
:
function
(
term
,
callback
)
{
return
_this
.
users
(
term
,
options
,
function
(
users
)
{
return
_this
.
users
(
term
,
options
,
function
(
users
)
{
// GitLabDropdownFilter returns this.instance
// GitLabDropdownRemote returns this.options.instance
const
glDropdown
=
this
.
instance
||
this
.
options
.
instance
;
glDropdown
.
options
.
processData
(
term
,
users
,
callback
);
}.
bind
(
this
));
}.
bind
(
this
),
);
},
processData
:
function
(
term
,
data
,
callback
)
{
let
users
=
data
;
...
...
@@ -228,13 +260,13 @@ function UsersSelect(currentUser, els, options = {}) {
// Potential duplicate entries when dealing with issue board
// because issue board is also managed by vue
const
selectedUsers
=
_
.
uniq
(
selectedInputs
,
false
,
a
=>
a
.
value
)
.
filter
((
input
)
=>
{
.
filter
(
input
=>
{
const
userId
=
parseInt
(
input
.
value
,
10
);
const
inUsersArray
=
users
.
find
(
u
=>
u
.
id
===
userId
);
return
!
inUsersArray
&&
userId
!==
0
;
})
.
map
((
input
)
=>
{
.
map
(
input
=>
{
const
userId
=
parseInt
(
input
.
value
,
10
);
const
{
avatarUrl
,
avatar_url
,
name
,
username
}
=
input
.
dataset
;
return
{
...
...
@@ -272,7 +304,7 @@ function UsersSelect(currentUser, els, options = {}) {
users
.
unshift
({
beforeDivider
:
true
,
name
:
'
Unassigned
'
,
id
:
0
id
:
0
,
});
}
if
(
showAnyUser
)
{
...
...
@@ -284,7 +316,7 @@ function UsersSelect(currentUser, els, options = {}) {
anyUser
=
{
beforeDivider
:
true
,
name
:
name
,
id
:
null
id
:
null
,
};
users
.
unshift
(
anyUser
);
}
...
...
@@ -310,7 +342,7 @@ function UsersSelect(currentUser, els, options = {}) {
users
=
users
.
filter
(
u
=>
selected
.
indexOf
(
u
.
id
)
===
-
1
);
selectedUsers
.
forEach
((
selectedUser
)
=>
{
selectedUsers
.
forEach
(
selectedUser
=>
{
showDivider
+=
1
;
users
.
splice
(
showDivider
,
0
,
selectedUser
);
});
...
...
@@ -328,7 +360,7 @@ function UsersSelect(currentUser, els, options = {}) {
filterable
:
true
,
filterRemote
:
true
,
search
:
{
fields
:
[
'
name
'
,
'
username
'
]
fields
:
[
'
name
'
,
'
username
'
],
},
selectable
:
true
,
fieldName
:
$dropdown
.
data
(
'
fieldName
'
),
...
...
@@ -384,8 +416,9 @@ function UsersSelect(currentUser, els, options = {}) {
if
(
$dropdown
.
hasClass
(
'
js-multiselect
'
))
{
const
isActive
=
$el
.
hasClass
(
'
is-active
'
);
const
previouslySelected
=
$dropdown
.
closest
(
'
.selectbox
'
)
.
find
(
"
input[name='
"
+
(
$dropdown
.
data
(
'
fieldName
'
))
+
"
'][value!=0]
"
);
const
previouslySelected
=
$dropdown
.
closest
(
'
.selectbox
'
)
.
find
(
"
input[name='
"
+
$dropdown
.
data
(
'
fieldName
'
)
+
"
'][value!=0]
"
);
// Enables support for limiting the number of users selected
// Automatically removes the first on the list if more users are selected
...
...
@@ -403,8 +436,9 @@ function UsersSelect(currentUser, els, options = {}) {
emitSidebarEvent
(
'
sidebar.addAssignee
'
,
user
);
// Remove unassigned selection (if it was previously selected)
const
unassignedSelected
=
$dropdown
.
closest
(
'
.selectbox
'
)
.
find
(
"
input[name='
"
+
(
$dropdown
.
data
(
'
fieldName
'
))
+
"
'][value=0]
"
);
const
unassignedSelected
=
$dropdown
.
closest
(
'
.selectbox
'
)
.
find
(
"
input[name='
"
+
$dropdown
.
data
(
'
fieldName
'
)
+
"
'][value=0]
"
);
if
(
unassignedSelected
)
{
unassignedSelected
.
remove
();
...
...
@@ -429,11 +463,14 @@ function UsersSelect(currentUser, els, options = {}) {
var
isIssueIndex
,
isMRIndex
,
page
,
selected
;
page
=
$
(
'
body
'
).
attr
(
'
data-page
'
);
isIssueIndex
=
page
===
'
projects:issues:index
'
;
isMRIndex
=
(
page
===
page
&&
page
===
'
projects:merge_requests:index
'
);
if
(
$dropdown
.
hasClass
(
'
js-filter-bulk-update
'
)
||
$dropdown
.
hasClass
(
'
js-issuable-form-dropdown
'
))
{
isMRIndex
=
page
===
page
&&
page
===
'
projects:merge_requests:index
'
;
if
(
$dropdown
.
hasClass
(
'
js-filter-bulk-update
'
)
||
$dropdown
.
hasClass
(
'
js-issuable-form-dropdown
'
)
)
{
e
.
preventDefault
();
const
isSelecting
=
(
user
.
id
!==
selectedId
)
;
const
isSelecting
=
user
.
id
!==
selectedId
;
selectedId
=
isSelecting
?
user
.
id
:
selectedIdDefault
;
if
(
selectedId
===
gon
.
current_user_id
)
{
...
...
@@ -453,20 +490,25 @@ function UsersSelect(currentUser, els, options = {}) {
}
else
if
(
$dropdown
.
hasClass
(
'
js-filter-submit
'
))
{
return
$dropdown
.
closest
(
'
form
'
).
submit
();
}
else
if
(
!
$dropdown
.
hasClass
(
'
js-multiselect
'
))
{
selected
=
$dropdown
.
closest
(
'
.selectbox
'
).
find
(
"
input[name='
"
+
(
$dropdown
.
data
(
'
fieldName
'
))
+
"
']
"
).
val
();
selected
=
$dropdown
.
closest
(
'
.selectbox
'
)
.
find
(
"
input[name='
"
+
$dropdown
.
data
(
'
fieldName
'
)
+
"
']
"
)
.
val
();
return
assignTo
(
selected
);
}
// Automatically close dropdown after assignee is selected
// since CE has no multiple assignees
// EE does not have a max-select
if
(
$dropdown
.
data
(
'
maxSelect
'
)
&&
getSelected
().
length
===
$dropdown
.
data
(
'
maxSelect
'
))
{
if
(
$dropdown
.
data
(
'
maxSelect
'
)
&&
getSelected
().
length
===
$dropdown
.
data
(
'
maxSelect
'
)
)
{
// Close the dropdown
$dropdown
.
dropdown
(
'
toggle
'
);
}
},
id
:
function
(
user
)
{
id
:
function
(
user
)
{
return
user
.
id
;
},
opened
:
function
(
e
)
{
...
...
@@ -492,7 +534,7 @@ function UsersSelect(currentUser, els, options = {}) {
updateLabel
:
$dropdown
.
data
(
'
dropdownTitle
'
),
renderRow
:
function
(
user
)
{
var
avatar
,
img
,
listClosingTags
,
listWithName
,
listWithUserName
,
username
;
username
=
user
.
username
?
"
@
"
+
user
.
username
:
""
;
username
=
user
.
username
?
'
@
'
+
user
.
username
:
''
;
avatar
=
user
.
avatar_url
?
user
.
avatar_url
:
gon
.
default_avatar_url
;
let
selected
=
false
;
...
...
@@ -501,7 +543,9 @@ function UsersSelect(currentUser, els, options = {}) {
selected
=
getSelected
().
find
(
u
=>
user
.
id
===
u
);
const
{
fieldName
}
=
this
;
const
field
=
$dropdown
.
closest
(
'
.selectbox
'
).
find
(
"
input[name='
"
+
fieldName
+
"
'][value='
"
+
user
.
id
+
"
']
"
);
const
field
=
$dropdown
.
closest
(
'
.selectbox
'
)
.
find
(
"
input[name='
"
+
fieldName
+
"
'][value='
"
+
user
.
id
+
"
']
"
);
if
(
field
.
length
)
{
selected
=
true
;
...
...
@@ -510,9 +554,11 @@ function UsersSelect(currentUser, els, options = {}) {
selected
=
user
.
id
===
selectedId
;
}
img
=
""
;
img
=
''
;
if
(
user
.
beforeDivider
!=
null
)
{
`<li><a href='#' class='
${
selected
===
true
?
'
is-active
'
:
''
}
'>
${
_
.
escape
(
user
.
name
)}
</a></li>`
;
`<li><a href='#' class='
${
selected
===
true
?
'
is-active
'
:
''
}
'>
${
_
.
escape
(
user
.
name
,
)}
</a></li>`
;
}
else
{
img
=
"
<img src='
"
+
avatar
+
"
' class='avatar avatar-inline' width='32' />
"
;
}
...
...
@@ -528,11 +574,13 @@ function UsersSelect(currentUser, els, options = {}) {
</a>
</li>
`
;
}
},
});
};
})(
this
));
$
(
'
.ajax-users-select
'
).
each
((
function
(
_this
)
{
})(
this
),
);
$
(
'
.ajax-users-select
'
).
each
(
(
function
(
_this
)
{
return
function
(
i
,
select
)
{
var
firstUser
,
showAnyUser
,
showEmailUser
,
showNullUser
;
var
options
=
{};
...
...
@@ -547,14 +595,14 @@ function UsersSelect(currentUser, els, options = {}) {
showEmailUser
=
$
(
select
).
data
(
'
emailUser
'
);
firstUser
=
$
(
select
).
data
(
'
firstUser
'
);
return
$
(
select
).
select2
({
placeholder
:
"
Search for a user
"
,
placeholder
:
'
Search for a user
'
,
multiple
:
$
(
select
).
hasClass
(
'
multiselect
'
),
minimumInputLength
:
0
,
query
:
function
(
query
)
{
return
_this
.
users
(
query
.
term
,
options
,
function
(
users
)
{
var
anyUser
,
data
,
emailUser
,
index
,
len
,
name
,
nullUser
,
obj
,
ref
;
data
=
{
results
:
users
results
:
users
,
};
if
(
query
.
term
.
length
===
0
)
{
if
(
firstUser
)
{
...
...
@@ -573,7 +621,7 @@ function UsersSelect(currentUser, els, options = {}) {
if
(
showNullUser
)
{
nullUser
=
{
name
:
'
Unassigned
'
,
id
:
0
id
:
0
,
};
data
.
results
.
unshift
(
nullUser
);
}
...
...
@@ -584,7 +632,7 @@ function UsersSelect(currentUser, els, options = {}) {
}
anyUser
=
{
name
:
name
,
id
:
null
id
:
null
,
};
data
.
results
.
unshift
(
anyUser
);
}
...
...
@@ -592,10 +640,10 @@ function UsersSelect(currentUser, els, options = {}) {
if
(
showEmailUser
&&
data
.
results
.
length
===
0
&&
query
.
term
.
match
(
/^
[^
@
]
+@
[^
@
]
+$/
))
{
var
trimmed
=
query
.
term
.
trim
();
emailUser
=
{
name
:
"
Invite
\"
"
+
trimmed
+
"
\"
by email
"
,
name
:
'
Invite "
'
+
trimmed
+
'
" by email
'
,
username
:
trimmed
,
id
:
trimmed
,
invite
:
true
invite
:
true
,
};
data
.
results
.
unshift
(
emailUser
);
}
...
...
@@ -617,25 +665,26 @@ function UsersSelect(currentUser, els, options = {}) {
args
=
1
<=
arguments
.
length
?
[].
slice
.
call
(
arguments
,
0
)
:
[];
return
_this
.
formatSelection
.
apply
(
_this
,
args
);
},
dropdownCssClass
:
"
ajax-users-dropdown
"
,
dropdownCssClass
:
'
ajax-users-dropdown
'
,
// we do not want to escape markup since we are displaying html in results
escapeMarkup
:
function
(
m
)
{
return
m
;
}
},
});
};
})(
this
));
})(
this
),
);
}
UsersSelect
.
prototype
.
initSelection
=
function
(
element
,
callback
)
{
var
id
,
nullUser
;
id
=
$
(
element
).
val
();
if
(
id
===
"
0
"
)
{
if
(
id
===
'
0
'
)
{
nullUser
=
{
name
:
'
Unassigned
'
name
:
'
Unassigned
'
,
};
return
callback
(
nullUser
);
}
else
if
(
id
!==
""
)
{
}
else
if
(
id
!==
''
)
{
return
this
.
user
(
id
,
callback
);
}
};
...
...
@@ -647,7 +696,17 @@ UsersSelect.prototype.formatResult = function(user) {
}
else
{
avatar
=
gon
.
default_avatar_url
;
}
return
"
<div class='user-result
"
+
(
!
user
.
username
?
'
no-username
'
:
void
0
)
+
"
'> <div class='user-image'><img class='avatar avatar-inline s32' src='
"
+
avatar
+
"
'></div> <div class='user-name dropdown-menu-user-full-name'>
"
+
_
.
escape
(
user
.
name
)
+
"
</div> <div class='user-username dropdown-menu-user-username'>
"
+
(
!
user
.
invite
?
"
@
"
+
_
.
escape
(
user
.
username
)
:
""
)
+
"
</div> </div>
"
;
return
(
"
<div class='user-result
"
+
(
!
user
.
username
?
'
no-username
'
:
void
0
)
+
"
'> <div class='user-image'><img class='avatar avatar-inline s32' src='
"
+
avatar
+
"
'></div> <div class='user-name dropdown-menu-user-full-name'>
"
+
_
.
escape
(
user
.
name
)
+
"
</div> <div class='user-username dropdown-menu-user-username'>
"
+
(
!
user
.
invite
?
'
@
'
+
_
.
escape
(
user
.
username
)
:
''
)
+
'
</div> </div>
'
);
};
UsersSelect
.
prototype
.
formatSelection
=
function
(
user
)
{
...
...
@@ -662,8 +721,7 @@ UsersSelect.prototype.user = function(user_id, callback) {
var
url
;
url
=
this
.
buildUrl
(
this
.
userPath
);
url
=
url
.
replace
(
'
:id
'
,
user_id
);
return
axios
.
get
(
url
)
.
then
(({
data
})
=>
{
return
axios
.
get
(
url
).
then
(({
data
})
=>
{
callback
(
data
);
});
};
...
...
@@ -682,10 +740,9 @@ UsersSelect.prototype.users = function(query, options, callback) {
todo_state_filter
:
options
.
todoStateFilter
||
null
,
current_user
:
options
.
showCurrentUser
||
null
,
author_id
:
options
.
authorId
||
null
,
skip_users
:
options
.
skipUsers
||
null
skip_users
:
options
.
skipUsers
||
null
,
};
return
axios
.
get
(
url
,
{
params
})
.
then
(({
data
})
=>
{
return
axios
.
get
(
url
,
{
params
}).
then
(({
data
})
=>
{
callback
(
data
);
});
};
...
...
app/assets/javascripts/zen_mode.js
View file @
c559bcca
...
...
@@ -47,16 +47,26 @@ export default class ZenMode {
e
.
preventDefault
();
return
$
(
e
.
currentTarget
).
trigger
(
'
zen_mode:leave
'
);
});
$
(
document
).
on
(
'
zen_mode:enter
'
,
(
function
(
_this
)
{
$
(
document
).
on
(
'
zen_mode:enter
'
,
(
function
(
_this
)
{
return
function
(
e
)
{
return
_this
.
enter
(
$
(
e
.
target
).
closest
(
'
.md-area
'
).
find
(
'
.zen-backdrop
'
));
return
_this
.
enter
(
$
(
e
.
target
)
.
closest
(
'
.md-area
'
)
.
find
(
'
.zen-backdrop
'
),
);
};
})(
this
));
$
(
document
).
on
(
'
zen_mode:leave
'
,
(
function
(
_this
)
{
})(
this
),
);
$
(
document
).
on
(
'
zen_mode:leave
'
,
(
function
(
_this
)
{
return
function
(
e
)
{
return
_this
.
exit
();
};
})(
this
));
})(
this
),
);
$
(
document
).
on
(
'
keydown
'
,
function
(
e
)
{
// Esc
if
(
e
.
keyCode
===
27
)
{
...
...
@@ -93,7 +103,7 @@ export default class ZenMode {
scrollTo
(
zen_area
)
{
return
$
.
scrollTo
(
zen_area
,
0
,
{
offset
:
-
150
offset
:
-
150
,
});
}
}
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