Commit 34f689e4 authored by Clement Ho's avatar Clement Ho

[skip ci] Add ability to assign yourself using vue component

parent 4b333fd0
...@@ -844,7 +844,13 @@ GitLabDropdown = (function() { ...@@ -844,7 +844,13 @@ GitLabDropdown = (function() {
if (instance == null) { if (instance == null) {
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) { GitLabDropdown.prototype.clearField = function(field, isInput) {
......
...@@ -86,22 +86,25 @@ ...@@ -86,22 +86,25 @@
} }
}); });
assignTo = function(selected) { assignTo = function(selected) {
var data; var data;
data = {}; data = {};
data[abilityName] = {}; data[abilityName] = {};
data[abilityName].assignee_id = selected != null ? selected : null; data[abilityName].assignee_id = selected != null ? selected : null;
$loading.fadeIn(); $loading.fadeIn();
$dropdown.trigger('loading.gl.dropdown'); $dropdown.trigger('loading.gl.dropdown');
return $.ajax({ return $.ajax({
type: 'PUT', type: 'PUT',
dataType: 'json', dataType: 'json',
url: issueURL, url: issueURL,
data: data data: data
}).done(function(data) { }).done(function(data) {
var user; var user;
$dropdown.trigger('loaded.gl.dropdown'); $dropdown.trigger('loaded.gl.dropdown');
$loading.fadeOut(); $loading.fadeOut();
$selectbox.hide(); // $selectbox.hide();
if (data.assignee) { if (data.assignee) {
user = { user = {
name: data.assignee.name, name: data.assignee.name,
...@@ -193,14 +196,16 @@ ...@@ -193,14 +196,16 @@
} }
}, },
defaultLabel: defaultLabel, defaultLabel: defaultLabel,
inputId: 'issue_assignee_id', // inputId: 'issue_assignee_id',
hidden: function(e) { hidden: function(e) {
$selectbox.hide(); $selectbox.hide();
// display:block overrides the hide-collapse rule // display:block overrides the hide-collapse rule
return $value.css('display', ''); return $value.css('display', '');
}, },
multiSelect: $dropdown.hasClass('js-multiselect'),
vue: $dropdown.hasClass('js-issue-board-sidebar'), vue: $dropdown.hasClass('js-issue-board-sidebar'),
clicked: function(user, $el, e) { clicked: function(user, $el, e) {
var isIssueIndex, isMRIndex, page, selected; var isIssueIndex, isMRIndex, page, selected;
page = $('body').data('page'); page = $('body').data('page');
isIssueIndex = page === 'projects:issues:index'; isIssueIndex = page === 'projects:issues:index';
...@@ -246,29 +251,57 @@ ...@@ -246,29 +251,57 @@
opened: function(e) { opened: function(e) {
const $el = $(e.currentTarget); const $el = $(e.currentTarget);
$el.find('.is-active').removeClass('is-active'); $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) { renderRow: function(user) {
var avatar, img, listClosingTags, listWithName, listWithUserName, selected, username; var avatar, img, listClosingTags, listWithName, listWithUserName, selected, username;
username = user.username ? "@" + user.username : ""; username = user.username ? "@" + user.username : "";
avatar = user.avatar_url ? user.avatar_url : false; 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 = ""; img = "";
if (user.beforeDivider != null) { 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 { } else {
if (avatar) { if (avatar) {
img = "<img src='" + avatar + "' class='avatar avatar-inline' width='30' />"; img = "<img src='" + avatar + "' class='avatar avatar-inline' width='30' />";
} }
} }
// split into three parts so we can remove the username section if nessesary // 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>"; const listItem = `
listWithUserName = "<span class='dropdown-menu-user-username'> " + username + " </span>"; <li data-user-id=${user.id}>
listClosingTags = "</a> </li>"; <a href='#' class='dropdown-menu-user-link ${selected === true ? 'is-active' : ''}'>
if (username === '') { ${img}
listWithUserName = ''; <strong class='dropdown-menu-user-full-name'>
} ${user.name}
return listWithName + listWithUserName + listClosingTags; </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;
} }
}); });
}; };
......
...@@ -6,11 +6,12 @@ export default { ...@@ -6,11 +6,12 @@ export default {
}, },
methods: { methods: {
assignSelf() { assignSelf() {
// const options = { this.service.add(this.assignees.currentUser.id).then((response) => {
const assignee = response.assignee;
// } this.assignees.addUser(assignee.name, assignee.username, assignee.avatar_url);
// this.service.save(options); }).catch((err) => {
this.assignees.addUser(); console.log('error')
});
} }
}, },
template: ` template: `
......
...@@ -15,9 +15,16 @@ const sidebarAssigneesOptions = () => ({ ...@@ -15,9 +15,16 @@ const sidebarAssigneesOptions = () => ({
const selector = this.$options.el; const selector = this.$options.el;
const element = document.querySelector(selector); const element = document.querySelector(selector);
const path = element.dataset.path; const path = element.dataset.path;
const field = element.dataset.field;
const service = new SidebarAssigneesService(path); const currentUser = {
const assignees = new SidebarAssigneesStore(); 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 { return {
assignees, assignees,
......
import Vue from 'vue'; import Vue from 'vue';
import VueResource from 'vue-resource'; import VueResource from 'vue-resource';
require('~/vue_shared/vue_resource_interceptor');
Vue.http.options.emulateJSON = true;
Vue.use(VueResource); Vue.use(VueResource);
export default class SidebarAssigneesService { export default class SidebarAssigneesService {
constructor(path) { constructor(path, field) {
this.field = field;
this.sidebarAssigneeResource = Vue.resource(path); this.sidebarAssigneeResource = Vue.resource(path);
} }
save(data) { add(userId) {
return this.sidebarAssigneeResource.save(data); return new Promise((resolve, reject) => {
this.sidebarAssigneeResource.update({ [this.field]: userId })
.then((response) => {
resolve(JSON.parse(response.body))
}, (response) => {
reject(response)
});
});
} }
} }
export default class SidebarAssigneesStore { export default class SidebarAssigneesStore {
constructor() { constructor(currentUser) {
this.currentUser = currentUser;
this.users = [{ this.users = [{
avatarUrl: 'http://www.gravatar.com/avatar/7e65550957227bd38fe2d7fbc6fd2f7b?s=80&d=identicon', avatarUrl: 'http://www.gravatar.com/avatar/7e65550957227bd38fe2d7fbc6fd2f7b?s=80&d=identicon',
name: 'test', name: 'Administrator',
username: 'username', username: 'username',
}, { }, {
avatarUrl: 'http://www.gravatar.com/avatar/7e65550957227bd38fe2d7fbc6fd2f7b?s=80&d=identicon', avatarUrl: 'http://www.gravatar.com/avatar/7e65550957227bd38fe2d7fbc6fd2f7b?s=80&d=identicon',
...@@ -36,6 +38,10 @@ export default class SidebarAssigneesStore { ...@@ -36,6 +38,10 @@ export default class SidebarAssigneesStore {
}); });
} }
addCurrentUser() {
this.users.push(this.currentUser);
}
removeUser(username) { removeUser(username) {
this.users = this.users.filter((u) => u.username !== username); this.users = this.users.filter((u) => u.username !== username);
} }
......
...@@ -24,7 +24,7 @@ ...@@ -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| = 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 .block.assignee
- if issuable.instance_of?(Issue) - 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 .title.hide-collapsed
Assignee Assignee
= icon('spinner spin', class: 'block-loading', 'aria-hidden': 'true') = icon('spinner spin', class: 'block-loading', 'aria-hidden': 'true')
...@@ -60,9 +60,10 @@ ...@@ -60,9 +60,10 @@
assign yourself assign yourself
.selectbox.hide-collapsed .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) - 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 - 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 } }) = 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 @@ ...@@ -211,6 +212,12 @@
= project_ref = project_ref
= clipboard_button(clipboard_text: project_ref, title: "Copy reference to clipboard", placement: "left") = 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 :javascript
gl.IssuableResource = new gl.SubbableResource('#{issuable_json_path(issuable)}'); gl.IssuableResource = new gl.SubbableResource('#{issuable_json_path(issuable)}');
new gl.IssuableTimeTracking("#{escape_javascript(serialize_issuable(issuable))}"); new gl.IssuableTimeTracking("#{escape_javascript(serialize_issuable(issuable))}");
......
...@@ -45,7 +45,7 @@ var config = { ...@@ -45,7 +45,7 @@ var config = {
u2f: ['vendor/u2f'], u2f: ['vendor/u2f'],
users: './users/users_bundle.js', users: './users/users_bundle.js',
vue_pipelines: './vue_pipelines_index/index.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: { output: {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment