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
34f689e4
Commit
34f689e4
authored
Mar 21, 2017
by
Clement Ho
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[skip ci] Add ability to assign yourself using vue component
parent
4b333fd0
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
100 additions
and
29 deletions
+100
-29
app/assets/javascripts/gl_dropdown.js
app/assets/javascripts/gl_dropdown.js
+7
-1
app/assets/javascripts/users_select.js
app/assets/javascripts/users_select.js
+45
-12
app/assets/javascripts/vue_sidebar_assignees/components/no_assignee.js
...vascripts/vue_sidebar_assignees/components/no_assignee.js
+6
-5
app/assets/javascripts/vue_sidebar_assignees/index.js
app/assets/javascripts/vue_sidebar_assignees/index.js
+9
-2
app/assets/javascripts/vue_sidebar_assignees/services/sidebar_assignees_service.js
...e_sidebar_assignees/services/sidebar_assignees_service.js
+14
-3
app/assets/javascripts/vue_sidebar_assignees/stores/sidebar_assignees_store.js
...s/vue_sidebar_assignees/stores/sidebar_assignees_store.js
+8
-2
app/views/shared/issuable/_sidebar.html.haml
app/views/shared/issuable/_sidebar.html.haml
+10
-3
config/webpack.config.js
config/webpack.config.js
+1
-1
No files found.
app/assets/javascripts/gl_dropdown.js
View file @
34f689e4
...
...
@@ -844,7 +844,13 @@ GitLabDropdown = (function() {
if
(
instance
==
null
)
{
instance
=
null
;
}
return
$
(
this
.
el
).
find
(
"
.dropdown-toggle-text
"
).
text
(
this
.
options
.
toggleLabel
(
selected
,
el
,
instance
));
let
toggleText
=
this
.
options
.
toggleLabel
(
selected
,
el
,
instance
);
if
(
this
.
options
.
updateLabel
)
{
toggleText
=
this
.
options
.
updateLabel
;
}
return
$
(
this
.
el
).
find
(
"
.dropdown-toggle-text
"
).
text
(
toggleText
);
};
GitLabDropdown
.
prototype
.
clearField
=
function
(
field
,
isInput
)
{
...
...
app/assets/javascripts/users_select.js
View file @
34f689e4
...
...
@@ -86,22 +86,25 @@
}
});
assignTo
=
function
(
selected
)
{
var
data
;
data
=
{};
data
[
abilityName
]
=
{};
data
[
abilityName
].
assignee_id
=
selected
!=
null
?
selected
:
null
;
$loading
.
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
();
$selectbox
.
hide
();
//
$selectbox.hide();
if
(
data
.
assignee
)
{
user
=
{
name
:
data
.
assignee
.
name
,
...
...
@@ -193,14 +196,16 @@
}
},
defaultLabel
:
defaultLabel
,
inputId
:
'
issue_assignee_id
'
,
//
inputId: 'issue_assignee_id',
hidden
:
function
(
e
)
{
$selectbox
.
hide
();
// display:block overrides the hide-collapse rule
return
$value
.
css
(
'
display
'
,
''
);
},
multiSelect
:
$dropdown
.
hasClass
(
'
js-multiselect
'
),
vue
:
$dropdown
.
hasClass
(
'
js-issue-board-sidebar
'
),
clicked
:
function
(
user
,
$el
,
e
)
{
var
isIssueIndex
,
isMRIndex
,
page
,
selected
;
page
=
$
(
'
body
'
).
data
(
'
page
'
);
isIssueIndex
=
page
===
'
projects:issues:index
'
;
...
...
@@ -246,29 +251,57 @@
opened
:
function
(
e
)
{
const
$el
=
$
(
e
.
currentTarget
);
$el
.
find
(
'
.is-active
'
).
removeClass
(
'
is-active
'
);
$el
.
find
(
`li[data-user-id="
${
selectedId
}
"] .dropdown-menu-user-link`
).
addClass
(
'
is-active
'
);
const
initialSelected
=
$selectbox
.
find
(
'
input[name="
'
+
$dropdown
.
data
(
'
field-name
'
)
+
'
"]
'
)
.
map
(
function
()
{
return
this
.
value
;
}).
get
().
forEach
((
selectedId
)
=>
{
$el
.
find
(
`li[data-user-id="
${
selectedId
}
"] .dropdown-menu-user-link`
).
addClass
(
'
is-active
'
);
});
},
updateLabel
:
$dropdown
.
data
(
'
dropdown-title
'
),
renderRow
:
function
(
user
)
{
var
avatar
,
img
,
listClosingTags
,
listWithName
,
listWithUserName
,
selected
,
username
;
username
=
user
.
username
?
"
@
"
+
user
.
username
:
""
;
avatar
=
user
.
avatar_url
?
user
.
avatar_url
:
false
;
selected
=
user
.
id
===
parseInt
(
selectedId
,
10
)
?
"
is-active
"
:
""
;
fieldName
=
this
.
fieldName
;
field
=
$dropdown
.
closest
(
'
.selectbox
'
).
find
(
"
input[name='
"
+
fieldName
+
"
'][value='
"
+
user
.
id
+
"
']
"
);
// debugger
if
(
field
.
length
)
{
selected
=
true
;
}
// selected = user.id === parseInt(selectedId, 10) ? "is-active" : "";
img
=
""
;
if
(
user
.
beforeDivider
!=
null
)
{
"
<li> <a href='#' class='
"
+
selected
+
"
'>
"
+
user
.
name
+
"
</a> </li>
"
;
`<li><a href='#' class='
${
selected
===
true
?
'
is-active
'
:
''
}
'>
${
user
.
name
}
</a></li>`
;
}
else
{
if
(
avatar
)
{
img
=
"
<img src='
"
+
avatar
+
"
' class='avatar avatar-inline' width='30' />
"
;
}
}
// split into three parts so we can remove the username section if nessesary
listWithName
=
"
<li data-user-id=
"
+
user
.
id
+
"
> <a href='#' class='dropdown-menu-user-link
"
+
selected
+
"
'>
"
+
img
+
"
<strong class='dropdown-menu-user-full-name'>
"
+
user
.
name
+
"
</strong>
"
;
listWithUserName
=
"
<span class='dropdown-menu-user-username'>
"
+
username
+
"
</span>
"
;
listClosingTags
=
"
</a> </li>
"
;
if
(
username
===
''
)
{
listWithUserName
=
''
;
}
return
listWithName
+
listWithUserName
+
listClosingTags
;
const
listItem
=
`
<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>
`
;
// listWithUserName = "<span class='dropdown-menu-user-username'> " + username + " </span>";
// listClosingTags = "</a> </li>";
// if (username === '') {
// listWithUserName = '';
// }
// debugger
// return listWithName + listWithUserName + listClosingTags;
return
listItem
;
}
});
};
...
...
app/assets/javascripts/vue_sidebar_assignees/components/no_assignee.js
View file @
34f689e4
...
...
@@ -6,11 +6,12 @@ export default {
},
methods
:
{
assignSelf
()
{
// const options = {
// }
// this.service.save(options);
this
.
assignees
.
addUser
();
this
.
service
.
add
(
this
.
assignees
.
currentUser
.
id
).
then
((
response
)
=>
{
const
assignee
=
response
.
assignee
;
this
.
assignees
.
addUser
(
assignee
.
name
,
assignee
.
username
,
assignee
.
avatar_url
);
}).
catch
((
err
)
=>
{
console
.
log
(
'
error
'
)
});
}
},
template
:
`
...
...
app/assets/javascripts/vue_sidebar_assignees/index.js
View file @
34f689e4
...
...
@@ -15,9 +15,16 @@ const sidebarAssigneesOptions = () => ({
const
selector
=
this
.
$options
.
el
;
const
element
=
document
.
querySelector
(
selector
);
const
path
=
element
.
dataset
.
path
;
const
field
=
element
.
dataset
.
field
;
const
service
=
new
SidebarAssigneesService
(
path
);
const
assignees
=
new
SidebarAssigneesStore
();
const
currentUser
=
{
id
:
parseInt
(
element
.
dataset
.
userId
,
10
),
name
:
element
.
dataset
.
name
,
username
:
element
.
dataset
.
username
,
}
const
service
=
new
SidebarAssigneesService
(
path
,
field
);
const
assignees
=
new
SidebarAssigneesStore
(
currentUser
);
return
{
assignees
,
...
...
app/assets/javascripts/vue_sidebar_assignees/services/sidebar_assignees_service.js
View file @
34f689e4
import
Vue
from
'
vue
'
;
import
VueResource
from
'
vue-resource
'
;
require
(
'
~/vue_shared/vue_resource_interceptor
'
);
Vue
.
http
.
options
.
emulateJSON
=
true
;
Vue
.
use
(
VueResource
);
export
default
class
SidebarAssigneesService
{
constructor
(
path
)
{
constructor
(
path
,
field
)
{
this
.
field
=
field
;
this
.
sidebarAssigneeResource
=
Vue
.
resource
(
path
);
}
save
(
data
)
{
return
this
.
sidebarAssigneeResource
.
save
(
data
);
add
(
userId
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
this
.
sidebarAssigneeResource
.
update
({
[
this
.
field
]:
userId
})
.
then
((
response
)
=>
{
resolve
(
JSON
.
parse
(
response
.
body
))
},
(
response
)
=>
{
reject
(
response
)
});
});
}
}
app/assets/javascripts/vue_sidebar_assignees/stores/sidebar_assignees_store.js
View file @
34f689e4
export
default
class
SidebarAssigneesStore
{
constructor
()
{
constructor
(
currentUser
)
{
this
.
currentUser
=
currentUser
;
this
.
users
=
[{
avatarUrl
:
'
http://www.gravatar.com/avatar/7e65550957227bd38fe2d7fbc6fd2f7b?s=80&d=identicon
'
,
name
:
'
test
'
,
name
:
'
Administrator
'
,
username
:
'
username
'
,
},
{
avatarUrl
:
'
http://www.gravatar.com/avatar/7e65550957227bd38fe2d7fbc6fd2f7b?s=80&d=identicon
'
,
...
...
@@ -36,6 +38,10 @@ export default class SidebarAssigneesStore {
});
}
addCurrentUser
()
{
this
.
users
.
push
(
this
.
currentUser
);
}
removeUser
(
username
)
{
this
.
users
=
this
.
users
.
filter
((
u
)
=>
u
.
username
!==
username
);
}
...
...
app/views/shared/issuable/_sidebar.html.haml
View file @
34f689e4
...
...
@@ -24,7 +24,7 @@
=
form_for
[
@project
.
namespace
.
becomes
(
Namespace
),
@project
,
issuable
],
remote:
true
,
format: :json
,
html:
{
class:
'issuable-context-form inline-update js-issuable-update'
}
do
|
f
|
.block.assignee
-
if
issuable
.
instance_of?
(
Issue
)
#js-vue-sidebar-assignees
{
data:
{
path:
issuable_json_path
(
issuable
)
}
}
#js-vue-sidebar-assignees
{
data:
{
path:
issuable_json_path
(
issuable
)
,
field:
"#{issuable.to_ability_name}[assignee_id]"
,
user:
{
id:
current_user
.
id
,
name:
current_user
.
name
,
username:
current_user
.
username
}
}
}
.title.hide-collapsed
Assignee
=
icon
(
'spinner spin'
,
class:
'block-loading'
,
'aria-hidden'
:
'true'
)
...
...
@@ -60,9 +60,10 @@
assign yourself
.selectbox.hide-collapsed
=
f
.
hidden_field
'assignee_id'
,
value:
issuable
.
assignee_id
,
id:
'issue_assignee_id'
-
issuable
.
assignees
.
each
do
|
assignee
|
=
hidden_field_tag
"
#{
issuable
.
to_ability_name
}
[assignee_ids][]"
,
assignee
.
id
,
id:
nil
-
if
issuable
.
instance_of?
(
Issue
)
=
dropdown_tag
(
'Select assignee(s)'
,
options:
{
toggle_class:
'js-user-search js-author-search
'
,
title:
'Assign to'
,
filter:
true
,
dropdown_class:
'dropdown-menu-user dropdown-menu-selectable dropdown-menu-author'
,
placeholder:
'Search users'
,
data:
{
first_user:
(
current_user
.
username
if
current_user
),
current_user:
true
,
project_id:
(
@project
.
id
if
@project
),
author_id:
issuable
.
author_id
,
field_name:
"
#{
issuable
.
to_ability_name
}
[assignee_id]"
,
issue_update:
issuable_json_path
(
issuable
),
ability_name:
issuable
.
to_ability_name
,
null_user:
true
}
})
=
dropdown_tag
(
'Select assignee(s)'
,
options:
{
toggle_class:
'js-user-search js-author-search
js-multiselect'
,
title:
'Assign to'
,
filter:
true
,
dropdown_class:
'dropdown-menu-user dropdown-menu-selectable dropdown-menu-author'
,
placeholder:
'Search users'
,
data:
{
first_user:
(
current_user
.
username
if
current_user
),
current_user:
true
,
project_id:
(
@project
.
id
if
@project
),
author_id:
issuable
.
author_id
,
field_name:
"
#{
issuable
.
to_ability_name
}
[assignee_ids][]"
,
issue_update:
issuable_json_path
(
issuable
),
ability_name:
issuable
.
to_ability_name
,
null_user:
true
,
'dropdown-title'
=>
'Select assignee(s)'
}
})
-
else
=
dropdown_tag
(
'Select assignee'
,
options:
{
toggle_class:
'js-user-search js-author-search'
,
title:
'Assign to'
,
filter:
true
,
dropdown_class:
'dropdown-menu-user dropdown-menu-selectable dropdown-menu-author'
,
placeholder:
'Search users'
,
data:
{
first_user:
(
current_user
.
username
if
current_user
),
current_user:
true
,
project_id:
(
@project
.
id
if
@project
),
author_id:
issuable
.
author_id
,
field_name:
"
#{
issuable
.
to_ability_name
}
[assignee_id]"
,
issue_update:
issuable_json_path
(
issuable
),
ability_name:
issuable
.
to_ability_name
,
null_user:
true
}
})
...
...
@@ -211,6 +212,12 @@
=
project_ref
=
clipboard_button
(
clipboard_text:
project_ref
,
title:
"Copy reference to clipboard"
,
placement:
"left"
)
-
issuable
.
assignees
.
each
do
|
assignee
|
:javascript
//document.addEventListener('DOMContentLoaded', () => {
// gl.sidebarAssigneesOptions.assignees.addUser("
#{
assignee
.
name
}
"
,
"
#{
assignee
.
username
}
"
,
"
#{
assignee
.
avatar_url
}
"
);
//});
:javascript
gl
.
IssuableResource
=
new
gl
.
SubbableResource
(
'
#{
issuable_json_path
(
issuable
)
}
'
);
new
gl
.
IssuableTimeTracking
(
"
#{
escape_javascript
(
serialize_issuable
(
issuable
))
}
"
);
...
...
config/webpack.config.js
View file @
34f689e4
...
...
@@ -45,7 +45,7 @@ var config = {
u2f
:
[
'
vendor/u2f
'
],
users
:
'
./users/users_bundle.js
'
,
vue_pipelines
:
'
./vue_pipelines_index/index.js
'
,
vue_sidebar_assignees
:
'
./vue_sidebar_assignees/index.js
'
,
vue_sidebar_assignees
:
'
./vue_sidebar_assignees/index.js
'
,
},
output
:
{
...
...
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