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() {
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) {
......
......@@ -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;
}
});
};
......
......@@ -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: `
......
......@@ -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,
......
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)
});
});
}
}
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);
}
......
......@@ -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))}");
......
......@@ -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: {
......
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