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
0
Merge Requests
0
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
Boxiang Sun
gitlab-ce
Commits
05278b2f
Commit
05278b2f
authored
May 12, 2017
by
Luke "Jared" Bennett
Committed by
Phil Hughes
May 12, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import export users select
parent
8c4e4020
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
609 additions
and
605 deletions
+609
-605
app/assets/javascripts/dispatcher.js
app/assets/javascripts/dispatcher.js
+14
-1
app/assets/javascripts/issuable_context.js
app/assets/javascripts/issuable_context.js
+1
-1
app/assets/javascripts/issuable_form.js
app/assets/javascripts/issuable_form.js
+2
-1
app/assets/javascripts/todos.js
app/assets/javascripts/todos.js
+2
-1
app/assets/javascripts/users_select.js
app/assets/javascripts/users_select.js
+590
-596
app/views/import/fogbugz/new_user_map.html.haml
app/views/import/fogbugz/new_user_map.html.haml
+0
-3
app/views/shared/issuable/_filter.html.haml
app/views/shared/issuable/_filter.html.haml
+0
-1
app/views/shared/issuable/_search_bar.html.haml
app/views/shared/issuable/_search_bar.html.haml
+0
-1
No files found.
app/assets/javascripts/dispatcher.js
View file @
05278b2f
...
...
@@ -14,7 +14,6 @@
/* global NotificationsForm */
/* global TreeView */
/* global NotificationsDropdown */
/* global UsersSelect */
/* global GroupAvatar */
/* global LineHighlighter */
/* global ProjectFork */
...
...
@@ -52,6 +51,7 @@ import ShortcutsWiki from './shortcuts_wiki';
import
Pipelines
from
'
./pipelines
'
;
import
BlobViewer
from
'
./blob/viewer/index
'
;
import
AutoWidthDropdownSelect
from
'
./issuable/auto_width_dropdown_select
'
;
import
UsersSelect
from
'
./users_select
'
;
const
ShortcutsBlob
=
require
(
'
./shortcuts_blob
'
);
...
...
@@ -113,6 +113,7 @@ const ShortcutsBlob = require('./shortcuts_blob');
case
'
projects:boards:show
'
:
case
'
projects:boards:index
'
:
shortcut_handler
=
new
ShortcutsNavigation
();
new
UsersSelect
();
break
;
case
'
projects:builds:show
'
:
new
Build
();
...
...
@@ -127,6 +128,7 @@ const ShortcutsBlob = require('./shortcuts_blob');
prefixId
:
page
===
'
projects:merge_requests:index
'
?
'
merge_request_
'
:
'
issue_
'
,
});
shortcut_handler
=
new
ShortcutsNavigation
();
new
UsersSelect
();
break
;
case
'
projects:issues:show
'
:
new
Issue
();
...
...
@@ -139,6 +141,10 @@ const ShortcutsBlob = require('./shortcuts_blob');
new
Milestone
();
new
Sidebar
();
break
;
case
'
groups:issues
'
:
case
'
groups:merge_requests
'
:
new
UsersSelect
();
break
;
case
'
dashboard:todos:index
'
:
new
gl
.
Todos
();
break
;
...
...
@@ -223,6 +229,10 @@ const ShortcutsBlob = require('./shortcuts_blob');
case
'
dashboard:activity
'
:
new
gl
.
Activities
();
break
;
case
'
dashboard:issues
'
:
case
'
dashboard:merge_requests
'
:
new
UsersSelect
();
break
;
case
'
projects:commit:show
'
:
new
Commit
();
new
gl
.
Diff
();
...
...
@@ -377,6 +387,9 @@ const ShortcutsBlob = require('./shortcuts_blob');
new
LineHighlighter
();
new
BlobViewer
();
break
;
case
'
import:fogbugz:new_user_map
'
:
new
UsersSelect
();
break
;
}
switch
(
path
.
first
())
{
case
'
sessions
'
:
...
...
app/assets/javascripts/issuable_context.js
View file @
05278b2f
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-new, comma-dangle, quotes, prefer-arrow-callback, consistent-return, one-var, no-var, one-var-declaration-per-line, no-underscore-dangle, max-len */
/* global UsersSelect */
/* global bp */
import
Cookies
from
'
js-cookie
'
;
import
UsersSelect
from
'
./users_select
'
;
(
function
()
{
this
.
IssuableContext
=
(
function
()
{
...
...
app/assets/javascripts/issuable_form.js
View file @
05278b2f
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, no-use-before-define, no-useless-escape, no-new, quotes, object-shorthand, no-unused-vars, comma-dangle, no-alert, consistent-return, no-else-return, prefer-template, one-var, one-var-declaration-per-line, curly, max-len */
/* global GitLab */
/* global UsersSelect */
/* global ZenMode */
/* global Autosave */
/* global dateFormat */
/* global Pikaday */
import
UsersSelect
from
'
./users_select
'
;
(
function
()
{
this
.
IssuableForm
=
(
function
()
{
IssuableForm
.
prototype
.
issueMoveConfirmMsg
=
'
Are you sure you want to move this issue to another project?
'
;
...
...
app/assets/javascripts/todos.js
View file @
05278b2f
/* eslint-disable class-methods-use-this, no-unneeded-ternary, quote-props */
/* global UsersSelect */
import
UsersSelect
from
'
./users_select
'
;
class
Todos
{
constructor
()
{
...
...
app/assets/javascripts/users_select.js
View file @
05278b2f
...
...
@@ -5,655 +5,649 @@
// TODO: remove eventHub hack after code splitting refactor
window
.
emitSidebarEvent
=
window
.
emitSidebarEvent
||
$
.
noop
;
(
function
()
{
const
slice
=
[].
slice
;
this
.
UsersSelect
=
(
function
()
{
function
UsersSelect
(
currentUser
,
els
)
{
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
"
;
if
(
currentUser
!=
null
)
{
if
(
typeof
currentUser
===
'
object
'
)
{
this
.
currentUser
=
currentUser
;
}
else
{
this
.
currentUser
=
JSON
.
parse
(
currentUser
);
function
UsersSelect
(
currentUser
,
els
)
{
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
"
;
if
(
currentUser
!=
null
)
{
if
(
typeof
currentUser
===
'
object
'
)
{
this
.
currentUser
=
currentUser
;
}
else
{
this
.
currentUser
=
JSON
.
parse
(
currentUser
);
}
}
$els
=
$
(
els
);
if
(
!
els
)
{
$els
=
$
(
'
.js-user-search
'
);
}
$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
;
$dropdown
=
$
(
dropdown
);
options
.
projectId
=
$dropdown
.
data
(
'
project-id
'
);
options
.
groupId
=
$dropdown
.
data
(
'
group-id
'
);
options
.
showCurrentUser
=
$dropdown
.
data
(
'
current-user
'
);
options
.
todoFilter
=
$dropdown
.
data
(
'
todo-filter
'
);
options
.
todoStateFilter
=
$dropdown
.
data
(
'
todo-state-filter
'
);
showNullUser
=
$dropdown
.
data
(
'
null-user
'
);
defaultNullUser
=
$dropdown
.
data
(
'
null-user-default
'
);
showMenuAbove
=
$dropdown
.
data
(
'
showMenuAbove
'
);
showAnyUser
=
$dropdown
.
data
(
'
any-user
'
);
firstUser
=
$dropdown
.
data
(
'
first-user
'
);
options
.
authorId
=
$dropdown
.
data
(
'
author-id
'
);
defaultLabel
=
$dropdown
.
data
(
'
default-label
'
);
issueURL
=
$dropdown
.
data
(
'
issueUpdate
'
);
$selectbox
=
$dropdown
.
closest
(
'
.selectbox
'
);
$block
=
$selectbox
.
closest
(
'
.block
'
);
abilityName
=
$dropdown
.
data
(
'
ability-name
'
);
$value
=
$block
.
find
(
'
.value
'
);
$collapsedSidebar
=
$block
.
find
(
'
.sidebar-collapsed-user
'
);
$loading
=
$block
.
find
(
'
.block-loading
'
).
fadeOut
();
selectedIdDefault
=
(
defaultNullUser
&&
showNullUser
)
?
0
:
null
;
selectedId
=
$dropdown
.
data
(
'
selected
'
)
||
selectedIdDefault
;
const
assignYourself
=
function
()
{
const
unassignedSelected
=
$dropdown
.
closest
(
'
.selectbox
'
)
.
find
(
`input[name='
${
$dropdown
.
data
(
'
field-name
'
)}
'][value=0]`
);
if
(
unassignedSelected
)
{
unassignedSelected
.
remove
();
}
}
$els
=
$
(
els
);
// Save current selected user to the DOM
const
input
=
document
.
createElement
(
'
input
'
);
input
.
type
=
'
hidden
'
;
input
.
name
=
$dropdown
.
data
(
'
field-name
'
);
const
currentUserInfo
=
$dropdown
.
data
(
'
currentUserInfo
'
);
if
(
currentUserInfo
)
{
input
.
value
=
currentUserInfo
.
id
;
input
.
dataset
.
meta
=
currentUserInfo
.
name
;
}
else
if
(
_this
.
currentUser
)
{
input
.
value
=
_this
.
currentUser
.
id
;
}
if
(
!
els
)
{
$els
=
$
(
'
.js-user-search
'
);
if
(
$selectbox
)
{
$dropdown
.
parent
().
before
(
input
);
}
else
{
$dropdown
.
after
(
input
);
}
};
if
(
$block
[
0
])
{
$block
[
0
].
addEventListener
(
'
assignYourself
'
,
assignYourself
);
}
$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
;
$dropdown
=
$
(
dropdown
);
options
.
projectId
=
$dropdown
.
data
(
'
project-id
'
);
options
.
groupId
=
$dropdown
.
data
(
'
group-id
'
);
options
.
showCurrentUser
=
$dropdown
.
data
(
'
current-user
'
);
options
.
todoFilter
=
$dropdown
.
data
(
'
todo-filter
'
);
options
.
todoStateFilter
=
$dropdown
.
data
(
'
todo-state-filter
'
);
showNullUser
=
$dropdown
.
data
(
'
null-user
'
);
defaultNullUser
=
$dropdown
.
data
(
'
null-user-default
'
);
showMenuAbove
=
$dropdown
.
data
(
'
showMenuAbove
'
);
showAnyUser
=
$dropdown
.
data
(
'
any-user
'
);
firstUser
=
$dropdown
.
data
(
'
first-user
'
);
options
.
authorId
=
$dropdown
.
data
(
'
author-id
'
);
defaultLabel
=
$dropdown
.
data
(
'
default-label
'
);
issueURL
=
$dropdown
.
data
(
'
issueUpdate
'
);
$selectbox
=
$dropdown
.
closest
(
'
.selectbox
'
);
$block
=
$selectbox
.
closest
(
'
.block
'
);
abilityName
=
$dropdown
.
data
(
'
ability-name
'
);
$value
=
$block
.
find
(
'
.value
'
);
$collapsedSidebar
=
$block
.
find
(
'
.sidebar-collapsed-user
'
);
$loading
=
$block
.
find
(
'
.block-loading
'
).
fadeOut
();
selectedIdDefault
=
(
defaultNullUser
&&
showNullUser
)
?
0
:
null
;
selectedId
=
$dropdown
.
data
(
'
selected
'
)
||
selectedIdDefault
;
const
assignYourself
=
function
()
{
const
unassignedSelected
=
$dropdown
.
closest
(
'
.selectbox
'
)
.
find
(
`input[name='
${
$dropdown
.
data
(
'
field-name
'
)}
'][value=0]`
);
if
(
unassignedSelected
)
{
unassignedSelected
.
remove
();
}
const
getSelectedUserInputs
=
function
()
{
return
$selectbox
.
find
(
`input[name="
${
$dropdown
.
data
(
'
field-name
'
)}
"]`
);
};
const
getSelected
=
function
()
{
return
getSelectedUserInputs
()
.
map
((
index
,
input
)
=>
parseInt
(
input
.
value
,
10
))
.
get
();
};
const
checkMaxSelect
=
function
()
{
const
maxSelect
=
$dropdown
.
data
(
'
max-select
'
);
if
(
maxSelect
)
{
const
selected
=
getSelected
();
if
(
selected
.
length
>
maxSelect
)
{
const
firstSelectedId
=
selected
[
0
];
const
firstSelected
=
$dropdown
.
closest
(
'
.selectbox
'
)
.
find
(
`input[name='
${
$dropdown
.
data
(
'
field-name
'
)}
'][value=
${
firstSelectedId
}
]`
);
firstSelected
.
remove
();
emitSidebarEvent
(
'
sidebar.removeAssignee
'
,
{
id
:
firstSelectedId
,
});
}
}
};
const
getMultiSelectDropdownTitle
=
function
(
selectedUser
,
isSelected
)
{
const
selectedUsers
=
getSelected
()
.
filter
(
u
=>
u
!==
0
);
const
firstUser
=
getSelectedUserInputs
()
.
map
((
index
,
input
)
=>
({
name
:
input
.
dataset
.
meta
,
value
:
parseInt
(
input
.
value
,
10
),
}))
.
filter
(
u
=>
u
.
id
!==
0
)
.
get
(
0
);
if
(
selectedUsers
.
length
===
0
)
{
return
'
Unassigned
'
;
}
else
if
(
selectedUsers
.
length
===
1
)
{
return
firstUser
.
name
;
}
else
if
(
isSelected
)
{
const
otherSelected
=
selectedUsers
.
filter
(
s
=>
s
!==
selectedUser
.
id
);
return
`
${
selectedUser
.
name
}
+
${
otherSelected
.
length
}
more`
;
}
else
{
return
`
${
firstUser
.
name
}
+
${
selectedUsers
.
length
-
1
}
more`
;
}
};
// Save current selected user to the DOM
const
input
=
document
.
createElement
(
'
input
'
);
input
.
type
=
'
hidden
'
;
input
.
name
=
$dropdown
.
data
(
'
field-name
'
);
$
(
'
.assign-to-me-link
'
).
on
(
'
click
'
,
(
e
)
=>
{
e
.
preventDefault
();
$
(
e
.
currentTarget
).
hide
();
const
currentUserInfo
=
$dropdown
.
data
(
'
currentUserInfo
'
);
if
(
$dropdown
.
data
(
'
multiSelect
'
))
{
assignYourself
();
checkMaxSelect
();
if
(
currentUserInfo
)
{
input
.
value
=
currentUserInfo
.
id
;
input
.
dataset
.
meta
=
currentUserInfo
.
name
;
}
else
if
(
_this
.
currentUser
)
{
input
.
value
=
_this
.
currentUser
.
id
;
}
const
currentUserInfo
=
$dropdown
.
data
(
'
currentUserInfo
'
);
$dropdown
.
find
(
'
.dropdown-toggle-text
'
).
text
(
getMultiSelectDropdownTitle
(
currentUserInfo
)).
removeClass
(
'
is-default
'
);
}
else
{
const
$input
=
$
(
`input[name="
${
$dropdown
.
data
(
'
field-name
'
)}
"]`
);
$input
.
val
(
gon
.
current_user_id
);
selectedId
=
$input
.
val
();
$dropdown
.
find
(
'
.dropdown-toggle-text
'
).
text
(
gon
.
current_user_fullname
).
removeClass
(
'
is-default
'
);
}
});
if
(
$selectbox
)
{
$dropdown
.
parent
().
before
(
input
);
}
else
{
$dropdown
.
after
(
input
);
}
};
$block
.
on
(
'
click
'
,
'
.js-assign-yourself
'
,
(
e
)
=>
{
e
.
preventDefault
();
return
assignTo
(
_this
.
currentUser
.
id
);
});
if
(
$block
[
0
])
{
$block
[
0
].
addEventListener
(
'
assignYourself
'
,
assignYourself
);
assignTo
=
function
(
selected
)
{
var
data
;
data
=
{};
data
[
abilityName
]
=
{};
data
[
abilityName
].
assignee_id
=
selected
!=
null
?
selected
:
null
;
$loading
.
removeClass
(
'
hidden
'
).
fadeIn
();
$dropdown
.
trigger
(
'
loading.gl.dropdown
'
);
return
$
.
ajax
({
type
:
'
PUT
'
,
dataType
:
'
json
'
,
url
:
issueURL
,
data
:
data
}).
done
(
function
(
data
)
{
var
user
;
$dropdown
.
trigger
(
'
loaded.gl.dropdown
'
);
$loading
.
fadeOut
();
if
(
data
.
assignee
)
{
user
=
{
name
:
data
.
assignee
.
name
,
username
:
data
.
assignee
.
username
,
avatar
:
data
.
assignee
.
avatar_url
};
}
else
{
user
=
{
name
:
'
Unassigned
'
,
username
:
''
,
avatar
:
''
};
}
const
getSelectedUserInputs
=
function
()
{
return
$selectbox
.
find
(
`input[name="
${
$dropdown
.
data
(
'
field-name
'
)}
"]`
);
};
const
getSelected
=
function
()
{
return
getSelectedUserInputs
()
.
map
((
index
,
input
)
=>
parseInt
(
input
.
value
,
10
))
.
get
();
};
const
checkMaxSelect
=
function
()
{
const
maxSelect
=
$dropdown
.
data
(
'
max-select
'
);
if
(
maxSelect
)
{
const
selected
=
getSelected
();
if
(
selected
.
length
>
maxSelect
)
{
const
firstSelectedId
=
selected
[
0
];
const
firstSelected
=
$dropdown
.
closest
(
'
.selectbox
'
)
.
find
(
`input[name='
${
$dropdown
.
data
(
'
field-name
'
)}
'][value=
${
firstSelectedId
}
]`
);
firstSelected
.
remove
();
emitSidebarEvent
(
'
sidebar.removeAssignee
'
,
{
id
:
firstSelectedId
,
});
$value
.
html
(
assigneeTemplate
(
user
));
$collapsedSidebar
.
attr
(
'
title
'
,
user
.
name
).
tooltip
(
'
fixTitle
'
);
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> <% } %>
'
);
return
$dropdown
.
glDropdown
({
showMenuAbove
:
showMenuAbove
,
data
:
function
(
term
,
callback
)
{
var
isAuthorFilter
;
isAuthorFilter
=
$
(
'
.js-author-search
'
);
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
));
},
processData
:
function
(
term
,
users
,
callback
)
{
let
anyUser
;
let
index
;
let
j
;
let
len
;
let
name
;
let
obj
;
let
showDivider
;
if
(
term
.
length
===
0
)
{
showDivider
=
0
;
if
(
firstUser
)
{
// Move current user to the front of the list
for
(
index
=
j
=
0
,
len
=
users
.
length
;
j
<
len
;
index
=
(
j
+=
1
))
{
obj
=
users
[
index
];
if
(
obj
.
username
===
firstUser
)
{
users
.
splice
(
index
,
1
);
users
.
unshift
(
obj
);
break
;
}
}
}
};
const
getMultiSelectDropdownTitle
=
function
(
selectedUser
,
isSelected
)
{
const
selectedUsers
=
getSelected
()
.
filter
(
u
=>
u
!==
0
);
const
firstUser
=
getSelectedUserInputs
()
.
map
((
index
,
input
)
=>
({
name
:
input
.
dataset
.
meta
,
value
:
parseInt
(
input
.
value
,
10
),
}))
.
filter
(
u
=>
u
.
id
!==
0
)
.
get
(
0
);
if
(
selectedUsers
.
length
===
0
)
{
return
'
Unassigned
'
;
}
else
if
(
selectedUsers
.
length
===
1
)
{
return
firstUser
.
name
;
}
else
if
(
isSelected
)
{
const
otherSelected
=
selectedUsers
.
filter
(
s
=>
s
!==
selectedUser
.
id
);
return
`
${
selectedUser
.
name
}
+
${
otherSelected
.
length
}
more`
;
}
else
{
return
`
${
firstUser
.
name
}
+
${
selectedUsers
.
length
-
1
}
more`
;
if
(
showNullUser
)
{
showDivider
+=
1
;
users
.
unshift
({
beforeDivider
:
true
,
name
:
'
Unassigned
'
,
id
:
0
});
}
if
(
showAnyUser
)
{
showDivider
+=
1
;
name
=
showAnyUser
;
if
(
name
===
true
)
{
name
=
'
Any User
'
;
}
anyUser
=
{
beforeDivider
:
true
,
name
:
name
,
id
:
null
};
users
.
unshift
(
anyUser
);
}
};
$
(
'
.assign-to-me-link
'
).
on
(
'
click
'
,
(
e
)
=>
{
e
.
preventDefault
();
$
(
e
.
currentTarget
).
hide
();
if
(
$dropdown
.
data
(
'
multiSelect
'
))
{
assignYourself
();
checkMaxSelect
();
const
currentUserInfo
=
$dropdown
.
data
(
'
currentUserInfo
'
);
$dropdown
.
find
(
'
.dropdown-toggle-text
'
).
text
(
getMultiSelectDropdownTitle
(
currentUserInfo
)).
removeClass
(
'
is-default
'
);
}
else
{
const
$input
=
$
(
`input[name="
${
$dropdown
.
data
(
'
field-name
'
)}
"]`
);
$input
.
val
(
gon
.
current_user_id
);
selectedId
=
$input
.
val
();
$dropdown
.
find
(
'
.dropdown-toggle-text
'
).
text
(
gon
.
current_user_fullname
).
removeClass
(
'
is-default
'
);
if
(
showDivider
)
{
users
.
splice
(
showDivider
,
0
,
'
divider
'
);
}
});
$block
.
on
(
'
click
'
,
'
.js-assign-yourself
'
,
(
e
)
=>
{
e
.
preventDefault
();
return
assignTo
(
_this
.
currentUser
.
id
);
});
if
(
$dropdown
.
hasClass
(
'
js-multiselect
'
))
{
const
selected
=
getSelected
().
filter
(
i
=>
i
!==
0
);
assignTo
=
function
(
selected
)
{
var
data
;
data
=
{};
data
[
abilityName
]
=
{};
data
[
abilityName
].
assignee_id
=
selected
!=
null
?
selected
:
null
;
$loading
.
removeClass
(
'
hidden
'
).
fadeIn
();
$dropdown
.
trigger
(
'
loading.gl.dropdown
'
);
return
$
.
ajax
({
type
:
'
PUT
'
,
dataType
:
'
json
'
,
url
:
issueURL
,
data
:
data
}).
done
(
function
(
data
)
{
var
user
;
$dropdown
.
trigger
(
'
loaded.gl.dropdown
'
);
$loading
.
fadeOut
();
if
(
data
.
assignee
)
{
user
=
{
name
:
data
.
assignee
.
name
,
username
:
data
.
assignee
.
username
,
avatar
:
data
.
assignee
.
avatar_url
};
}
else
{
user
=
{
name
:
'
Unassigned
'
,
username
:
''
,
avatar
:
''
};
}
$value
.
html
(
assigneeTemplate
(
user
));
$collapsedSidebar
.
attr
(
'
title
'
,
user
.
name
).
tooltip
(
'
fixTitle
'
);
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> <% } %>
'
);
return
$dropdown
.
glDropdown
({
showMenuAbove
:
showMenuAbove
,
data
:
function
(
term
,
callback
)
{
var
isAuthorFilter
;
isAuthorFilter
=
$
(
'
.js-author-search
'
);
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
));
},
processData
:
function
(
term
,
users
,
callback
)
{
let
anyUser
;
let
index
;
let
j
;
let
len
;
let
name
;
let
obj
;
let
showDivider
;
if
(
term
.
length
===
0
)
{
showDivider
=
0
;
if
(
firstUser
)
{
// Move current user to the front of the list
for
(
index
=
j
=
0
,
len
=
users
.
length
;
j
<
len
;
index
=
(
j
+=
1
))
{
obj
=
users
[
index
];
if
(
obj
.
username
===
firstUser
)
{
users
.
splice
(
index
,
1
);
users
.
unshift
(
obj
);
break
;
}
}
}
if
(
showNullUser
)
{
if
(
selected
.
length
>
0
)
{
if
(
$dropdown
.
data
(
'
dropdown-header
'
))
{
showDivider
+=
1
;
users
.
unshift
({
beforeDivider
:
true
,
name
:
'
Unassigned
'
,
id
:
0
users
.
splice
(
showDivider
,
0
,
{
header
:
$dropdown
.
data
(
'
dropdown-header
'
),
});
}
if
(
showAnyUser
)
{
showDivider
+=
1
;
name
=
showAnyUser
;
if
(
name
===
true
)
{
name
=
'
Any User
'
;
}
anyUser
=
{
beforeDivider
:
true
,
name
:
name
,
id
:
null
};
users
.
unshift
(
anyUser
);
}
if
(
showDivider
)
{
users
.
splice
(
showDivider
,
0
,
'
divider
'
);
}
const
selectedUsers
=
users
.
filter
(
u
=>
selected
.
indexOf
(
u
.
id
)
!==
-
1
)
.
sort
((
a
,
b
)
=>
a
.
name
>
b
.
name
);
if
(
$dropdown
.
hasClass
(
'
js-multiselect
'
))
{
const
selected
=
getSelected
().
filter
(
i
=>
i
!==
0
);
users
=
users
.
filter
(
u
=>
selected
.
indexOf
(
u
.
id
)
===
-
1
);
if
(
selected
.
length
>
0
)
{
if
(
$dropdown
.
data
(
'
dropdown-header
'
))
{
showDivider
+=
1
;
users
.
splice
(
showDivider
,
0
,
{
header
:
$dropdown
.
data
(
'
dropdown-header
'
),
});
}
const
selectedUsers
=
users
.
filter
(
u
=>
selected
.
indexOf
(
u
.
id
)
!==
-
1
)
.
sort
((
a
,
b
)
=>
a
.
name
>
b
.
name
);
selectedUsers
.
forEach
((
selectedUser
)
=>
{
showDivider
+=
1
;
users
.
splice
(
showDivider
,
0
,
selectedUser
);
});
users
=
users
.
filter
(
u
=>
selected
.
indexOf
(
u
.
id
)
===
-
1
);
users
.
splice
(
showDivider
+
1
,
0
,
'
divider
'
);
}
}
}
selectedUsers
.
forEach
((
selectedUser
)
=>
{
showDivider
+=
1
;
users
.
splice
(
showDivider
,
0
,
selectedUser
);
});
callback
(
users
);
if
(
showMenuAbove
)
{
$dropdown
.
data
(
'
glDropdown
'
).
positionMenuAbove
();
}
},
filterable
:
true
,
filterRemote
:
true
,
search
:
{
fields
:
[
'
name
'
,
'
username
'
]
},
selectable
:
true
,
fieldName
:
$dropdown
.
data
(
'
field-name
'
),
toggleLabel
:
function
(
selected
,
el
,
glDropdown
)
{
const
inputValue
=
glDropdown
.
filterInput
.
val
();
if
(
this
.
multiSelect
&&
inputValue
===
''
)
{
// Remove non-users from the fullData array
const
users
=
glDropdown
.
filteredFullData
();
const
callback
=
glDropdown
.
parseData
.
bind
(
glDropdown
);
// Update the data model
this
.
processData
(
inputValue
,
users
,
callback
);
}
users
.
splice
(
showDivider
+
1
,
0
,
'
divider
'
);
}
}
}
if
(
this
.
multiSelect
)
{
return
getMultiSelectDropdownTitle
(
selected
,
$
(
el
).
hasClass
(
'
is-active
'
));
}
callback
(
users
);
if
(
showMenuAbove
)
{
$dropdown
.
data
(
'
glDropdown
'
).
positionMenuAbove
();
}
},
filterable
:
true
,
filterRemote
:
true
,
search
:
{
fields
:
[
'
name
'
,
'
username
'
]
},
selectable
:
true
,
fieldName
:
$dropdown
.
data
(
'
field-name
'
),
toggleLabel
:
function
(
selected
,
el
,
glDropdown
)
{
const
inputValue
=
glDropdown
.
filterInput
.
val
();
if
(
this
.
multiSelect
&&
inputValue
===
''
)
{
// Remove non-users from the fullData array
const
users
=
glDropdown
.
filteredFullData
();
const
callback
=
glDropdown
.
parseData
.
bind
(
glDropdown
);
// Update the data model
this
.
processData
(
inputValue
,
users
,
callback
);
}
if
(
selected
&&
'
id
'
in
selected
&&
$
(
el
).
hasClass
(
'
is-active
'
))
{
$dropdown
.
find
(
'
.dropdown-toggle-text
'
).
removeClass
(
'
is-default
'
);
if
(
selected
.
text
)
{
return
selected
.
text
;
}
else
{
return
selected
.
name
;
}
}
else
{
$dropdown
.
find
(
'
.dropdown-toggle-text
'
).
addClass
(
'
is-default
'
);
return
defaultLabel
;
}
},
defaultLabel
:
defaultLabel
,
hidden
:
function
(
e
)
{
if
(
$dropdown
.
hasClass
(
'
js-multiselect
'
))
{
emitSidebarEvent
(
'
sidebar.saveAssignees
'
);
}
if
(
this
.
multiSelect
)
{
return
getMultiSelectDropdownTitle
(
selected
,
$
(
el
).
hasClass
(
'
is-active
'
));
}
if
(
!
$dropdown
.
data
(
'
always-show-selectbox
'
))
{
$selectbox
.
hide
();
if
(
selected
&&
'
id
'
in
selected
&&
$
(
el
).
hasClass
(
'
is-active
'
))
{
$dropdown
.
find
(
'
.dropdown-toggle-text
'
).
removeClass
(
'
is-default
'
);
if
(
selected
.
text
)
{
return
selected
.
text
;
}
else
{
return
selected
.
name
;
}
}
else
{
$dropdown
.
find
(
'
.dropdown-toggle-text
'
).
addClass
(
'
is-default
'
);
return
defaultLabel
;
}
},
defaultLabel
:
defaultLabel
,
hidden
:
function
(
e
)
{
if
(
$dropdown
.
hasClass
(
'
js-multiselect
'
))
{
emitSidebarEvent
(
'
sidebar.saveAssignees
'
);
}
// Recalculate where .value is because vue might have changed it
$block
=
$selectbox
.
closest
(
'
.block
'
);
$value
=
$block
.
find
(
'
.value
'
);
// display:block overrides the hide-collapse rule
$value
.
css
(
'
display
'
,
''
);
}
},
multiSelect
:
$dropdown
.
hasClass
(
'
js-multiselect
'
),
inputMeta
:
$dropdown
.
data
(
'
input-meta
'
),
clicked
:
function
(
options
)
{
const
{
$el
,
e
,
isMarking
}
=
options
;
const
user
=
options
.
selectedObj
;
if
(
$dropdown
.
hasClass
(
'
js-multiselect
'
))
{
const
isActive
=
$el
.
hasClass
(
'
is-active
'
);
const
previouslySelected
=
$dropdown
.
closest
(
'
.selectbox
'
)
.
find
(
"
input[name='
"
+
(
$dropdown
.
data
(
'
field-name
'
))
+
"
'][value!=0]
"
);
// Enables support for limiting the number of users selected
// Automatically removes the first on the list if more users are selected
checkMaxSelect
();
if
(
user
.
beforeDivider
&&
user
.
name
.
toLowerCase
()
===
'
unassigned
'
)
{
// Unassigned selected
previouslySelected
.
each
((
index
,
element
)
=>
{
const
id
=
parseInt
(
element
.
value
,
10
);
element
.
remove
();
});
emitSidebarEvent
(
'
sidebar.removeAllAssignees
'
);
}
else
if
(
isActive
)
{
// user selected
emitSidebarEvent
(
'
sidebar.addAssignee
'
,
user
);
if
(
!
$dropdown
.
data
(
'
always-show-selectbox
'
))
{
$selectbox
.
hide
();
// Remove unassigned selection (if it was previously selected)
const
unassignedSelected
=
$dropdown
.
closest
(
'
.selectbox
'
)
.
find
(
"
input[name='
"
+
(
$dropdown
.
data
(
'
field-name
'
))
+
"
'][value=0]
"
);
// Recalculate where .value is because vue might have changed it
$block
=
$selectbox
.
closest
(
'
.block
'
);
$value
=
$block
.
find
(
'
.value
'
);
// display:block overrides the hide-collapse rule
$value
.
css
(
'
display
'
,
''
);
if
(
unassignedSelected
)
{
unassignedSelected
.
remove
();
}
}
else
{
if
(
previouslySelected
.
length
===
0
)
{
// Select unassigned because there is no more selected users
this
.
addInput
(
$dropdown
.
data
(
'
field-name
'
),
0
,
{});
}
},
multiSelect
:
$dropdown
.
hasClass
(
'
js-multiselect
'
),
inputMeta
:
$dropdown
.
data
(
'
input-meta
'
),
clicked
:
function
(
options
)
{
const
{
$el
,
e
,
isMarking
}
=
options
;
const
user
=
options
.
selectedObj
;
if
(
$dropdown
.
hasClass
(
'
js-multiselect
'
))
{
const
isActive
=
$el
.
hasClass
(
'
is-active
'
);
const
previouslySelected
=
$dropdown
.
closest
(
'
.selectbox
'
)
.
find
(
"
input[name='
"
+
(
$dropdown
.
data
(
'
field-name
'
))
+
"
'][value!=0]
"
);
// Enables support for limiting the number of users selected
// Automatically removes the first on the list if more users are selected
checkMaxSelect
();
if
(
user
.
beforeDivider
&&
user
.
name
.
toLowerCase
()
===
'
unassigned
'
)
{
// Unassigned selected
previouslySelected
.
each
((
index
,
element
)
=>
{
const
id
=
parseInt
(
element
.
value
,
10
);
element
.
remove
();
});
emitSidebarEvent
(
'
sidebar.removeAllAssignees
'
);
}
else
if
(
isActive
)
{
// user selected
emitSidebarEvent
(
'
sidebar.addAssignee
'
,
user
);
// Remove unassigned selection (if it was previously selected)
const
unassignedSelected
=
$dropdown
.
closest
(
'
.selectbox
'
)
.
find
(
"
input[name='
"
+
(
$dropdown
.
data
(
'
field-name
'
))
+
"
'][value=0]
"
);
// User unselected
emitSidebarEvent
(
'
sidebar.removeAssignee
'
,
user
);
}
if
(
unassignedSelected
)
{
unassignedSelected
.
remove
();
}
}
else
{
if
(
previouslySelected
.
length
===
0
)
{
// Select unassigned because there is no more selected users
this
.
addInput
(
$dropdown
.
data
(
'
field-name
'
),
0
,
{});
}
if
(
getSelected
().
find
(
u
=>
u
===
gon
.
current_user_id
))
{
$
(
'
.assign-to-me-link
'
).
hide
();
}
else
{
$
(
'
.assign-to-me-link
'
).
show
();
}
}
// User unselected
emitSidebarEvent
(
'
sidebar.removeAssignee
'
,
user
);
}
var
isIssueIndex
,
isMRIndex
,
page
,
selected
;
page
=
$
(
'
body
'
).
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
'
))
{
e
.
preventDefault
();
if
(
getSelected
().
find
(
u
=>
u
===
gon
.
current_user_id
))
{
$
(
'
.assign-to-me-link
'
).
hide
();
}
else
{
$
(
'
.assign-to-me-link
'
).
show
();
}
}
const
isSelecting
=
(
user
.
id
!==
selectedId
);
selectedId
=
isSelecting
?
user
.
id
:
selectedIdDefault
;
var
isIssueIndex
,
isMRIndex
,
page
,
selected
;
page
=
$
(
'
body
'
).
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
'
))
{
e
.
preventDefault
();
if
(
selectedId
===
gon
.
current_user_id
)
{
$
(
'
.assign-to-me-link
'
).
hide
();
}
else
{
$
(
'
.assign-to-me-link
'
).
show
();
}
return
;
}
if
(
$el
.
closest
(
'
.add-issues-modal
'
).
length
)
{
gl
.
issueBoards
.
ModalStore
.
store
.
filter
[
$dropdown
.
data
(
'
field-name
'
)]
=
user
.
id
;
}
else
if
(
$dropdown
.
hasClass
(
'
js-filter-submit
'
)
&&
(
isIssueIndex
||
isMRIndex
))
{
return
Issuable
.
filterResults
(
$dropdown
.
closest
(
'
form
'
));
}
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
(
'
field-name
'
))
+
"
']
"
).
val
();
return
assignTo
(
selected
);
}
},
id
:
function
(
user
)
{
return
user
.
id
;
},
opened
:
function
(
e
)
{
const
$el
=
$
(
e
.
currentTarget
);
if
(
$dropdown
.
hasClass
(
'
js-issue-board-sidebar
'
))
{
selectedId
=
parseInt
(
$dropdown
[
0
].
dataset
.
selected
,
10
)
||
selectedIdDefault
;
}
$el
.
find
(
'
.is-active
'
).
removeClass
(
'
is-active
'
);
const
isSelecting
=
(
user
.
id
!==
selectedId
);
selectedId
=
isSelecting
?
user
.
id
:
selectedIdDefault
;
function
highlightSelected
(
id
)
{
$el
.
find
(
`li[data-user-id="
${
id
}
"] .dropdown-menu-user-link`
).
addClass
(
'
is-active
'
);
}
if
(
selectedId
===
gon
.
current_user_id
)
{
$
(
'
.assign-to-me-link
'
).
hide
();
}
else
{
$
(
'
.assign-to-me-link
'
).
show
();
}
return
;
}
if
(
$el
.
closest
(
'
.add-issues-modal
'
).
length
)
{
gl
.
issueBoards
.
ModalStore
.
store
.
filter
[
$dropdown
.
data
(
'
field-name
'
)]
=
user
.
id
;
}
else
if
(
$dropdown
.
hasClass
(
'
js-filter-submit
'
)
&&
(
isIssueIndex
||
isMRIndex
))
{
return
Issuable
.
filterResults
(
$dropdown
.
closest
(
'
form
'
));
}
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
(
'
field-name
'
))
+
"
']
"
).
val
();
return
assignTo
(
selected
);
}
},
id
:
function
(
user
)
{
return
user
.
id
;
},
opened
:
function
(
e
)
{
const
$el
=
$
(
e
.
currentTarget
);
if
(
$dropdown
.
hasClass
(
'
js-issue-board-sidebar
'
))
{
selectedId
=
parseInt
(
$dropdown
[
0
].
dataset
.
selected
,
10
)
||
selectedIdDefault
;
}
$el
.
find
(
'
.is-active
'
).
removeClass
(
'
is-active
'
);
if
(
$selectbox
[
0
])
{
getSelected
().
forEach
(
selectedId
=>
highlightSelected
(
selectedId
));
}
else
{
highlightSelected
(
selectedId
);
}
},
updateLabel
:
$dropdown
.
data
(
'
dropdown-title
'
),
renderRow
:
function
(
user
)
{
var
avatar
,
img
,
listClosingTags
,
listWithName
,
listWithUserName
,
username
;
username
=
user
.
username
?
"
@
"
+
user
.
username
:
""
;
avatar
=
user
.
avatar_url
?
user
.
avatar_url
:
false
;
function
highlightSelected
(
id
)
{
$el
.
find
(
`li[data-user-id="
${
id
}
"] .dropdown-menu-user-link`
).
addClass
(
'
is-active
'
);
}
let
selected
=
user
.
id
===
parseInt
(
selectedId
,
10
);
if
(
$selectbox
[
0
])
{
getSelected
().
forEach
(
selectedId
=>
highlightSelected
(
selectedId
));
}
else
{
highlightSelected
(
selectedId
);
}
},
updateLabel
:
$dropdown
.
data
(
'
dropdown-title
'
),
renderRow
:
function
(
user
)
{
var
avatar
,
img
,
listClosingTags
,
listWithName
,
listWithUserName
,
username
;
username
=
user
.
username
?
"
@
"
+
user
.
username
:
""
;
avatar
=
user
.
avatar_url
?
user
.
avatar_url
:
false
;
if
(
this
.
multiSelect
)
{
const
fieldName
=
this
.
fieldName
;
const
field
=
$dropdown
.
closest
(
'
.selectbox
'
).
find
(
"
input[name='
"
+
fieldName
+
"
'][value='
"
+
user
.
id
+
"
']
"
);
let
selected
=
user
.
id
===
parseInt
(
selectedId
,
10
);
if
(
field
.
length
)
{
selected
=
true
;
}
}
if
(
this
.
multiSelect
)
{
const
fieldName
=
this
.
fieldName
;
const
field
=
$dropdown
.
closest
(
'
.selectbox
'
).
find
(
"
input[name='
"
+
fieldName
+
"
'][value='
"
+
user
.
id
+
"
']
"
);
img
=
""
;
if
(
user
.
beforeDivider
!=
null
)
{
`<li><a href='#' class='
${
selected
===
true
?
'
is-active
'
:
''
}
'>
${
user
.
name
}
</a></li>`
;
}
else
{
if
(
avatar
)
{
img
=
"
<img src='
"
+
avatar
+
"
' class='avatar avatar-inline' width='32' />
"
;
}
}
if
(
field
.
length
)
{
selected
=
true
;
return
`
<li data-user-id=
${
user
.
id
}
>
<a href='#' class='dropdown-menu-user-link
${
selected
===
true
?
'
is-active
'
:
''
}
'>
${
img
}
<strong class='dropdown-menu-user-full-name'>
${
user
.
name
}
</strong>
${
username
?
`<span class='dropdown-menu-user-username'>
${
username
}
</span>`
:
''
}
</a>
</li>
`
;
}
});
};
})(
this
));
$
(
'
.ajax-users-select
'
).
each
((
function
(
_this
)
{
return
function
(
i
,
select
)
{
var
firstUser
,
showAnyUser
,
showEmailUser
,
showNullUser
;
var
options
=
{};
options
.
skipLdap
=
$
(
select
).
hasClass
(
'
skip_ldap
'
);
options
.
projectId
=
$
(
select
).
data
(
'
project-id
'
);
options
.
groupId
=
$
(
select
).
data
(
'
group-id
'
);
options
.
showCurrentUser
=
$
(
select
).
data
(
'
current-user
'
);
options
.
pushCodeToProtectedBranches
=
$
(
select
).
data
(
'
push-code-to-protected-branches
'
);
options
.
authorId
=
$
(
select
).
data
(
'
author-id
'
);
options
.
skipUsers
=
$
(
select
).
data
(
'
skip-users
'
);
showNullUser
=
$
(
select
).
data
(
'
null-user
'
);
showAnyUser
=
$
(
select
).
data
(
'
any-user
'
);
showEmailUser
=
$
(
select
).
data
(
'
email-user
'
);
firstUser
=
$
(
select
).
data
(
'
first-user
'
);
return
$
(
select
).
select2
({
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
,
j
,
len
,
name
,
nullUser
,
obj
,
ref
;
data
=
{
results
:
users
};
if
(
query
.
term
.
length
===
0
)
{
if
(
firstUser
)
{
// Move current user to the front of the list
ref
=
data
.
results
;
for
(
index
=
j
=
0
,
len
=
ref
.
length
;
j
<
len
;
index
=
(
j
+=
1
))
{
obj
=
ref
[
index
];
if
(
obj
.
username
===
firstUser
)
{
data
.
results
.
splice
(
index
,
1
);
data
.
results
.
unshift
(
obj
);
break
;
}
}
}
img
=
""
;
if
(
user
.
beforeDivider
!=
null
)
{
`<li><a href='#' class='
${
selected
===
true
?
'
is-active
'
:
''
}
'>
${
user
.
name
}
</a></li>`
;
}
else
{
if
(
avatar
)
{
img
=
"
<img src='
"
+
avatar
+
"
' class='avatar avatar-inline' width='32' />
"
;
if
(
showNullUser
)
{
nullUser
=
{
name
:
'
Unassigned
'
,
id
:
0
};
data
.
results
.
unshift
(
nullUser
);
}
if
(
showAnyUser
)
{
name
=
showAnyUser
;
if
(
name
===
true
)
{
name
=
'
Any User
'
;
}
anyUser
=
{
name
:
name
,
id
:
null
};
data
.
results
.
unshift
(
anyUser
);
}
return
`
<li data-user-id=
${
user
.
id
}
>
<a href='#' class='dropdown-menu-user-link
${
selected
===
true
?
'
is-active
'
:
''
}
'>
${
img
}
<strong class='dropdown-menu-user-full-name'>
${
user
.
name
}
</strong>
${
username
?
`<span class='dropdown-menu-user-username'>
${
username
}
</span>`
:
''
}
</a>
</li>
`
;
}
});
};
})(
this
));
$
(
'
.ajax-users-select
'
).
each
((
function
(
_this
)
{
return
function
(
i
,
select
)
{
var
firstUser
,
showAnyUser
,
showEmailUser
,
showNullUser
;
var
options
=
{};
options
.
skipLdap
=
$
(
select
).
hasClass
(
'
skip_ldap
'
);
options
.
projectId
=
$
(
select
).
data
(
'
project-id
'
);
options
.
groupId
=
$
(
select
).
data
(
'
group-id
'
);
options
.
showCurrentUser
=
$
(
select
).
data
(
'
current-user
'
);
options
.
pushCodeToProtectedBranches
=
$
(
select
).
data
(
'
push-code-to-protected-branches
'
);
options
.
authorId
=
$
(
select
).
data
(
'
author-id
'
);
options
.
skipUsers
=
$
(
select
).
data
(
'
skip-users
'
);
showNullUser
=
$
(
select
).
data
(
'
null-user
'
);
showAnyUser
=
$
(
select
).
data
(
'
any-user
'
);
showEmailUser
=
$
(
select
).
data
(
'
email-user
'
);
firstUser
=
$
(
select
).
data
(
'
first-user
'
);
return
$
(
select
).
select2
({
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
,
j
,
len
,
name
,
nullUser
,
obj
,
ref
;
data
=
{
results
:
users
};
if
(
query
.
term
.
length
===
0
)
{
if
(
firstUser
)
{
// Move current user to the front of the list
ref
=
data
.
results
;
for
(
index
=
j
=
0
,
len
=
ref
.
length
;
j
<
len
;
index
=
(
j
+=
1
))
{
obj
=
ref
[
index
];
if
(
obj
.
username
===
firstUser
)
{
data
.
results
.
splice
(
index
,
1
);
data
.
results
.
unshift
(
obj
);
break
;
}
}
}
if
(
showNullUser
)
{
nullUser
=
{
name
:
'
Unassigned
'
,
id
:
0
};
data
.
results
.
unshift
(
nullUser
);
}
if
(
showAnyUser
)
{
name
=
showAnyUser
;
if
(
name
===
true
)
{
name
=
'
Any User
'
;
}
anyUser
=
{
name
:
name
,
id
:
null
};
data
.
results
.
unshift
(
anyUser
);
}
}
if
(
showEmailUser
&&
data
.
results
.
length
===
0
&&
query
.
term
.
match
(
/^
[^
@
]
+@
[^
@
]
+$/
))
{
var
trimmed
=
query
.
term
.
trim
();
emailUser
=
{
name
:
"
Invite
\"
"
+
query
.
term
+
"
\"
"
,
username
:
trimmed
,
id
:
trimmed
};
data
.
results
.
unshift
(
emailUser
);
}
return
query
.
callback
(
data
);
});
},
initSelection
:
function
()
{
var
args
;
args
=
1
<=
arguments
.
length
?
slice
.
call
(
arguments
,
0
)
:
[];
return
_this
.
initSelection
.
apply
(
_this
,
args
);
},
formatResult
:
function
()
{
var
args
;
args
=
1
<=
arguments
.
length
?
slice
.
call
(
arguments
,
0
)
:
[];
return
_this
.
formatResult
.
apply
(
_this
,
args
);
},
formatSelection
:
function
()
{
var
args
;
args
=
1
<=
arguments
.
length
?
slice
.
call
(
arguments
,
0
)
:
[];
return
_this
.
formatSelection
.
apply
(
_this
,
args
);
},
dropdownCssClass
:
"
ajax-users-dropdown
"
,
// we do not want to escape markup since we are displaying html in results
escapeMarkup
:
function
(
m
)
{
return
m
;
if
(
showEmailUser
&&
data
.
results
.
length
===
0
&&
query
.
term
.
match
(
/^
[^
@
]
+@
[^
@
]
+$/
))
{
var
trimmed
=
query
.
term
.
trim
();
emailUser
=
{
name
:
"
Invite
\"
"
+
query
.
term
+
"
\"
"
,
username
:
trimmed
,
id
:
trimmed
};
data
.
results
.
unshift
(
emailUser
);
}
return
query
.
callback
(
data
);
});
};
})(
this
));
}
UsersSelect
.
prototype
.
initSelection
=
function
(
element
,
callback
)
{
var
id
,
nullUser
;
id
=
$
(
element
).
val
();
if
(
id
===
"
0
"
)
{
nullUser
=
{
name
:
'
Unassigned
'
};
return
callback
(
nullUser
);
}
else
if
(
id
!==
""
)
{
return
this
.
user
(
id
,
callback
);
}
};
UsersSelect
.
prototype
.
formatResult
=
function
(
user
)
{
var
avatar
;
if
(
user
.
avatar_url
)
{
avatar
=
user
.
avatar_url
;
}
else
{
avatar
=
gon
.
default_avatar_url
;
}
return
"
<div class='user-result
"
+
(
!
user
.
username
?
'
no-username
'
:
void
0
)
+
"
'> <div class='user-image'><img class='avatar s24' src='
"
+
avatar
+
"
'></div> <div class='user-name'>
"
+
user
.
name
+
"
</div> <div class='user-username'>
"
+
(
user
.
username
||
""
)
+
"
</div> </div>
"
;
};
UsersSelect
.
prototype
.
formatSelection
=
function
(
user
)
{
return
user
.
name
;
};
UsersSelect
.
prototype
.
user
=
function
(
user_id
,
callback
)
{
if
(
!
/^
\d
+$/
.
test
(
user_id
))
{
return
false
;
}
var
url
;
url
=
this
.
buildUrl
(
this
.
userPath
);
url
=
url
.
replace
(
'
:id
'
,
user_id
);
return
$
.
ajax
({
url
:
url
,
dataType
:
"
json
"
}).
done
(
function
(
user
)
{
return
callback
(
user
);
});
};
// Return users list. Filtered by query
// Only active users retrieved
UsersSelect
.
prototype
.
users
=
function
(
query
,
options
,
callback
)
{
var
url
;
url
=
this
.
buildUrl
(
this
.
usersPath
);
return
$
.
ajax
({
url
:
url
,
data
:
{
search
:
query
,
per_page
:
20
,
active
:
true
,
project_id
:
options
.
projectId
||
null
,
group_id
:
options
.
groupId
||
null
,
skip_ldap
:
options
.
skipLdap
||
null
,
todo_filter
:
options
.
todoFilter
||
null
,
todo_state_filter
:
options
.
todoStateFilter
||
null
,
current_user
:
options
.
showCurrentUser
||
null
,
push_code_to_protected_branches
:
options
.
pushCodeToProtectedBranches
||
null
,
author_id
:
options
.
authorId
||
null
,
skip_users
:
options
.
skipUsers
||
null
},
dataType
:
"
json
"
}).
done
(
function
(
users
)
{
return
callback
(
users
);
initSelection
:
function
()
{
var
args
;
args
=
1
<=
arguments
.
length
?
[].
slice
.
call
(
arguments
,
0
)
:
[];
return
_this
.
initSelection
.
apply
(
_this
,
args
);
},
formatResult
:
function
()
{
var
args
;
args
=
1
<=
arguments
.
length
?
[].
slice
.
call
(
arguments
,
0
)
:
[];
return
_this
.
formatResult
.
apply
(
_this
,
args
);
},
formatSelection
:
function
()
{
var
args
;
args
=
1
<=
arguments
.
length
?
[].
slice
.
call
(
arguments
,
0
)
:
[];
return
_this
.
formatSelection
.
apply
(
_this
,
args
);
},
dropdownCssClass
:
"
ajax-users-dropdown
"
,
// we do not want to escape markup since we are displaying html in results
escapeMarkup
:
function
(
m
)
{
return
m
;
}
});
};
UsersSelect
.
prototype
.
buildUrl
=
function
(
url
)
{
if
(
gon
.
relative_url_root
!=
null
)
{
url
=
gon
.
relative_url_root
.
replace
(
/
\/
$/
,
''
)
+
url
;
}
return
url
;
})(
this
));
}
UsersSelect
.
prototype
.
initSelection
=
function
(
element
,
callback
)
{
var
id
,
nullUser
;
id
=
$
(
element
).
val
();
if
(
id
===
"
0
"
)
{
nullUser
=
{
name
:
'
Unassigned
'
};
return
UsersSelect
;
})();
}).
call
(
window
);
return
callback
(
nullUser
);
}
else
if
(
id
!==
""
)
{
return
this
.
user
(
id
,
callback
);
}
};
UsersSelect
.
prototype
.
formatResult
=
function
(
user
)
{
var
avatar
;
if
(
user
.
avatar_url
)
{
avatar
=
user
.
avatar_url
;
}
else
{
avatar
=
gon
.
default_avatar_url
;
}
return
"
<div class='user-result
"
+
(
!
user
.
username
?
'
no-username
'
:
void
0
)
+
"
'> <div class='user-image'><img class='avatar s24' src='
"
+
avatar
+
"
'></div> <div class='user-name'>
"
+
user
.
name
+
"
</div> <div class='user-username'>
"
+
(
user
.
username
||
""
)
+
"
</div> </div>
"
;
};
UsersSelect
.
prototype
.
formatSelection
=
function
(
user
)
{
return
user
.
name
;
};
UsersSelect
.
prototype
.
user
=
function
(
user_id
,
callback
)
{
if
(
!
/^
\d
+$/
.
test
(
user_id
))
{
return
false
;
}
var
url
;
url
=
this
.
buildUrl
(
this
.
userPath
);
url
=
url
.
replace
(
'
:id
'
,
user_id
);
return
$
.
ajax
({
url
:
url
,
dataType
:
"
json
"
}).
done
(
function
(
user
)
{
return
callback
(
user
);
});
};
// Return users list. Filtered by query
// Only active users retrieved
UsersSelect
.
prototype
.
users
=
function
(
query
,
options
,
callback
)
{
var
url
;
url
=
this
.
buildUrl
(
this
.
usersPath
);
return
$
.
ajax
({
url
:
url
,
data
:
{
search
:
query
,
per_page
:
20
,
active
:
true
,
project_id
:
options
.
projectId
||
null
,
group_id
:
options
.
groupId
||
null
,
skip_ldap
:
options
.
skipLdap
||
null
,
todo_filter
:
options
.
todoFilter
||
null
,
todo_state_filter
:
options
.
todoStateFilter
||
null
,
current_user
:
options
.
showCurrentUser
||
null
,
push_code_to_protected_branches
:
options
.
pushCodeToProtectedBranches
||
null
,
author_id
:
options
.
authorId
||
null
,
skip_users
:
options
.
skipUsers
||
null
},
dataType
:
"
json
"
}).
done
(
function
(
users
)
{
return
callback
(
users
);
});
};
UsersSelect
.
prototype
.
buildUrl
=
function
(
url
)
{
if
(
gon
.
relative_url_root
!=
null
)
{
url
=
gon
.
relative_url_root
.
replace
(
/
\/
$/
,
''
)
+
url
;
}
return
url
;
};
export
default
UsersSelect
;
app/views/import/fogbugz/new_user_map.html.haml
View file @
05278b2f
...
...
@@ -46,6 +46,3 @@
.form-actions
=
submit_tag
'Continue to the next step'
,
class:
'btn btn-create'
:javascript
new
UsersSelect
();
app/views/shared/issuable/_filter.html.haml
View file @
05278b2f
...
...
@@ -71,7 +71,6 @@
=
render
'shared/labels_row'
,
labels:
@labels
:javascript
new
UsersSelect
();
new
LabelsSelect
();
new
MilestoneSelect
();
new
IssueStatusSelect
();
...
...
app/views/shared/issuable/_search_bar.html.haml
View file @
05278b2f
...
...
@@ -150,7 +150,6 @@
-
unless
type
===
:boards_modal
:javascript
new
UsersSelect
();
new
LabelsSelect
();
new
MilestoneSelect
();
new
IssueStatusSelect
();
...
...
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