gitlab-org--gitlab-foss/app/assets/javascripts/todos.js.es6
Fatih Acet f879319840 Merge branch 'add-todo-toggle-event' into 'master'
Add todo toggle event

## What does this MR do?
Adds a custom jQuery event `todo:toggle` to detect when a new todo is added so that the respective todo counters (header navigation and sidebar) can update as needed

## Are there points in the code the reviewer needs to double check?

*  I wasn't sure whether each `spec` should be modularized based on the html templates or whether they should be separated based on function. There are some crossovers between the `dashboard_spec` and the `header_spec`.
* The naming conventions for `sidebar` and `right_sidebar` were a little confusing since they were named the opposite in their `specs`. I made a few assumptions and named a few files based on what I thought they should be named. I'd be happy to change it to something else though 😄  

## Why was this MR needed?
This resolves an existing issue where the todo count on the sidebar would not update (until refresh) and refactors the existing methods that are used to update the todo counters (header navigation and sidebar)

## What are the relevant issue numbers?
Closes #20140

## Does this MR meet the acceptance criteria?

- [x] [CHANGELOG](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CHANGELOG) entry added
- Tests
  - [x] Added for this feature/bug
  - [x] All builds are passing
- [x] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides)
- [x] Branch has no merge conflicts with `master` (if you do - rebase it please)
- [x] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)

See merge request !5724
2016-10-27 13:28:40 +00:00

163 lines
4.3 KiB
JavaScript

/* eslint-disable */
((global) => {
class Todos {
constructor({ el } = {}) {
this.allDoneClicked = this.allDoneClicked.bind(this);
this.doneClicked = this.doneClicked.bind(this);
this.el = el || $('.js-todos-options');
this.perPage = this.el.data('perPage');
this.clearListeners();
this.initBtnListeners();
this.initFilters();
}
clearListeners() {
$('.done-todo').off('click');
$('.js-todos-mark-all').off('click');
return $('.todo').off('click');
}
initBtnListeners() {
$('.done-todo').on('click', this.doneClicked);
$('.js-todos-mark-all').on('click', this.allDoneClicked);
return $('.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) {
event.preventDefault();
Turbolinks.visit(this.action + '&' + $(this).serialize());
});
}
initFilterDropdown($dropdown, fieldName, searchFields) {
$dropdown.glDropdown({
fieldName,
selectable: true,
filterable: searchFields ? true : false,
search: { fields: searchFields },
data: $dropdown.data('data'),
clicked: function() {
return $dropdown.closest('form.filter-form').submit();
}
})
}
doneClicked(e) {
e.preventDefault();
e.stopImmediatePropagation();
const $target = $(e.currentTarget);
$target.disable();
return $.ajax({
type: 'POST',
url: $target.attr('href'),
dataType: 'json',
data: {
'_method': 'delete'
},
success: (data) => {
this.redirectIfNeeded(data.count);
this.clearDone($target.closest('li'));
return this.updateBadges(data);
}
});
}
allDoneClicked(e) {
e.preventDefault();
e.stopImmediatePropagation();
$target = $(e.currentTarget);
$target.disable();
return $.ajax({
type: 'POST',
url: $target.attr('href'),
dataType: 'json',
data: {
'_method': 'delete'
},
success: (data) => {
$target.remove();
$('.prepend-top-default').html('<div class="nothing-here-block">You\'re all done!</div>');
return this.updateBadges(data);
}
});
}
clearDone($row) {
const $ul = $row.closest('ul');
$row.remove();
if (!$ul.find('li').length) {
return $ul.parents('.panel').remove();
}
}
updateBadges(data) {
$(document).trigger('todo:toggle', data.count);
$('.todos-pending .badge').text(data.count);
return $('.todos-done .badge').text(data.done_count);
}
getTotalPages() {
return this.el.data('totalPages');
}
getCurrentPage() {
return this.el.data('currentPage');
}
getTodosPerPage() {
return this.el.data('perPage');
}
redirectIfNeeded(total) {
const currPages = this.getTotalPages();
const currPage = this.getCurrentPage();
// Refresh if no remaining Todos
if (!total) {
window.location.reload();
return;
}
// Do nothing if no pagination
if (!currPages) {
return;
}
const newPages = Math.ceil(total / this.getTodosPerPage());
let url = location.href;
if (newPages !== currPages) {
// Redirect to previous page if there's one available
if (currPages > 1 && currPage === currPages) {
const pageParams = {
page: currPages - 1
};
url = gl.utils.mergeUrlParams(pageParams, url);
}
return Turbolinks.visit(url);
}
}
goToTodoUrl(e) {
const todoLink = $(this).data('url');
if (!todoLink) {
return;
}
// Allow Meta-Click or Mouse3-click to open in a new tab
if (e.metaKey || e.which === 2) {
e.preventDefault();
return window.open(todoLink, '_blank');
} else {
return Turbolinks.visit(todoLink);
}
}
}
global.Todos = Todos;
})(window.gl || (window.gl = {}));