Merge branch '27114-add-undo-to-todos-in-the-done-tab' into 'master'
Add 'Undo' to Todos in the Done tab Closes #27114 See merge request !8782
This commit is contained in:
commit
cc64eda987
|
@ -1,7 +1,6 @@
|
|||
/* eslint-disable class-methods-use-this, no-new, func-names, no-unneeded-ternary, object-shorthand, quote-props, no-param-reassign, max-len */
|
||||
/* eslint-disable class-methods-use-this, no-unneeded-ternary, quote-props */
|
||||
/* global UsersSelect */
|
||||
|
||||
((global) => {
|
||||
class Todos {
|
||||
constructor() {
|
||||
this.initFilters();
|
||||
|
@ -17,30 +16,30 @@
|
|||
}
|
||||
|
||||
unbindEvents() {
|
||||
$('.js-done-todo, .js-undo-todo').off('click', this.updateStateClickedWrapper);
|
||||
$('.js-done-todo, .js-undo-todo, .js-add-todo').off('click', this.updateRowStateClickedWrapper);
|
||||
$('.js-todos-mark-all').off('click', this.allDoneClickedWrapper);
|
||||
$('.todo').off('click', this.goToTodoUrl);
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
this.updateStateClickedWrapper = this.updateStateClicked.bind(this);
|
||||
this.updateRowStateClickedWrapper = this.updateRowStateClicked.bind(this);
|
||||
this.allDoneClickedWrapper = this.allDoneClicked.bind(this);
|
||||
|
||||
$('.js-done-todo, .js-undo-todo').on('click', this.updateStateClickedWrapper);
|
||||
$('.js-done-todo, .js-undo-todo, .js-add-todo').on('click', this.updateRowStateClickedWrapper);
|
||||
$('.js-todos-mark-all').on('click', this.allDoneClickedWrapper);
|
||||
$('.todo').on('click', this.goToTodoUrl);
|
||||
}
|
||||
|
||||
initFilters() {
|
||||
new UsersSelect();
|
||||
this.initFilterDropdown($('.js-project-search'), 'project_id', ['text']);
|
||||
this.initFilterDropdown($('.js-type-search'), 'type');
|
||||
this.initFilterDropdown($('.js-action-search'), 'action_id');
|
||||
|
||||
$('form.filter-form').on('submit', function (event) {
|
||||
$('form.filter-form').on('submit', function applyFilters(event) {
|
||||
event.preventDefault();
|
||||
gl.utils.visitUrl(`${this.action}&${$(this).serialize()}`);
|
||||
});
|
||||
return new UsersSelect();
|
||||
}
|
||||
|
||||
initFilterDropdown($dropdown, fieldName, searchFields) {
|
||||
|
@ -50,14 +49,13 @@
|
|||
filterable: searchFields ? true : false,
|
||||
search: { fields: searchFields },
|
||||
data: $dropdown.data('data'),
|
||||
clicked: function () {
|
||||
return $dropdown.closest('form.filter-form').submit();
|
||||
},
|
||||
clicked: () => $dropdown.closest('form.filter-form').submit(),
|
||||
});
|
||||
}
|
||||
|
||||
updateStateClicked(e) {
|
||||
updateRowStateClicked(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const target = e.target;
|
||||
target.setAttribute('disabled', '');
|
||||
target.classList.add('disabled');
|
||||
|
@ -69,8 +67,8 @@
|
|||
'_method': target.getAttribute('data-method'),
|
||||
},
|
||||
success: (data) => {
|
||||
this.updateState(target);
|
||||
this.updateBadges(data);
|
||||
this.updateRowState(target);
|
||||
return this.updateBadges(data);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -94,28 +92,30 @@
|
|||
});
|
||||
}
|
||||
|
||||
updateState(target) {
|
||||
updateRowState(target) {
|
||||
const row = target.closest('li');
|
||||
const restoreBtn = row.querySelector('.js-undo-todo');
|
||||
const doneBtn = row.querySelector('.js-done-todo');
|
||||
|
||||
target.classList.add('hidden');
|
||||
target.removeAttribute('disabled');
|
||||
target.classList.remove('disabled');
|
||||
target.classList.add('hidden');
|
||||
|
||||
if (target === doneBtn) {
|
||||
row.classList.add('done-reversible');
|
||||
restoreBtn.classList.remove('hidden');
|
||||
} else {
|
||||
} else if (target === restoreBtn) {
|
||||
row.classList.remove('done-reversible');
|
||||
doneBtn.classList.remove('hidden');
|
||||
} else {
|
||||
row.parentNode.removeChild(row);
|
||||
}
|
||||
}
|
||||
|
||||
updateBadges(data) {
|
||||
$(document).trigger('todo:toggle', data.count);
|
||||
$('.todos-pending .badge').text(data.count);
|
||||
$('.todos-done .badge').text(data.done_count);
|
||||
document.querySelector('.todos-pending .badge').innerHTML = data.count;
|
||||
document.querySelector('.todos-done .badge').innerHTML = data.done_count;
|
||||
}
|
||||
|
||||
goToTodoUrl(e) {
|
||||
|
@ -142,5 +142,5 @@
|
|||
}
|
||||
}
|
||||
|
||||
global.Todos = Todos;
|
||||
})(window.gl || (window.gl = {}));
|
||||
window.gl = window.gl || {};
|
||||
gl.Todos = Todos;
|
||||
|
|
|
@ -42,3 +42,8 @@
|
|||
= link_to restore_dashboard_todo_path(todo), method: :patch, class: 'btn btn-loading js-undo-todo hidden' do
|
||||
Undo
|
||||
= icon('spinner spin')
|
||||
- else
|
||||
.todo-actions
|
||||
= link_to restore_dashboard_todo_path(todo), method: :patch, class: 'btn btn-loading js-add-todo' do
|
||||
Add todo
|
||||
= icon('spinner spin')
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Add Undo to Todos in the Done tab
|
||||
merge_request: 8782
|
||||
author: Jacopo Beschi @jacopo-beschi
|
|
@ -38,7 +38,9 @@ describe 'Dashboard Todos', feature: true do
|
|||
|
||||
shared_examples 'deleting the todo' do
|
||||
before do
|
||||
first('.js-done-todo').click
|
||||
within first('.todo') do
|
||||
click_link 'Done'
|
||||
end
|
||||
end
|
||||
|
||||
it 'is marked as done-reversible in the list' do
|
||||
|
@ -62,9 +64,11 @@ describe 'Dashboard Todos', feature: true do
|
|||
|
||||
shared_examples 'deleting and restoring the todo' do
|
||||
before do
|
||||
first('.js-done-todo').click
|
||||
within first('.todo') do
|
||||
click_link 'Done'
|
||||
wait_for_ajax
|
||||
first('.js-undo-todo').click
|
||||
click_link 'Undo'
|
||||
end
|
||||
end
|
||||
|
||||
it 'is marked back as pending in the list' do
|
||||
|
@ -97,6 +101,35 @@ describe 'Dashboard Todos', feature: true do
|
|||
end
|
||||
end
|
||||
|
||||
context 'User has done todos', js: true do
|
||||
before do
|
||||
create(:todo, :mentioned, :done, user: user, project: project, target: issue, author: author)
|
||||
login_as(user)
|
||||
visit dashboard_todos_path(state: :done)
|
||||
end
|
||||
|
||||
it 'has the done todo present' do
|
||||
expect(page).to have_selector('.todos-list .todo.todo-done', count: 1)
|
||||
end
|
||||
|
||||
describe 'restoring the todo' do
|
||||
before do
|
||||
within first('.todo') do
|
||||
click_link 'Add todo'
|
||||
end
|
||||
end
|
||||
|
||||
it 'is removed from the list' do
|
||||
expect(page).not_to have_selector('.todos-list .todo.todo-done')
|
||||
end
|
||||
|
||||
it 'updates todo count' do
|
||||
expect(page).to have_content 'To do 1'
|
||||
expect(page).to have_content 'Done 0'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'User has Todos with labels spanning multiple projects' do
|
||||
before do
|
||||
label1 = create(:label, project: project)
|
||||
|
@ -143,7 +176,7 @@ describe 'Dashboard Todos', feature: true do
|
|||
describe 'mark all as done', js: true do
|
||||
before do
|
||||
visit dashboard_todos_path
|
||||
click_link('Mark all as done')
|
||||
click_link 'Mark all as done'
|
||||
end
|
||||
|
||||
it 'shows "All done" message!' do
|
||||
|
|
Loading…
Reference in New Issue