2021-12-11 22:18:48 +05:30
|
|
|
/* eslint-disable class-methods-use-this */
|
2018-05-09 12:01:36 +05:30
|
|
|
|
|
|
|
import $ from 'jquery';
|
2021-04-29 21:17:54 +05:30
|
|
|
import { getGroups } from '~/api/groups_api';
|
|
|
|
import { getProjects } from '~/api/projects_api';
|
2020-11-24 15:15:51 +05:30
|
|
|
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
|
2023-05-27 22:25:52 +05:30
|
|
|
import { createAlert } from '~/alert';
|
2021-03-11 19:13:27 +05:30
|
|
|
import axios from '~/lib/utils/axios_utils';
|
2019-12-21 20:55:43 +05:30
|
|
|
import { addDelimiter } from '~/lib/utils/text_utility';
|
2018-03-27 19:54:05 +05:30
|
|
|
import { __ } from '~/locale';
|
2021-03-11 19:13:27 +05:30
|
|
|
import UsersSelect from '~/users_select';
|
2017-09-10 17:25:29 +05:30
|
|
|
|
|
|
|
export default class Todos {
|
2017-08-17 22:00:37 +05:30
|
|
|
constructor() {
|
|
|
|
this.initFilters();
|
|
|
|
this.bindEvents();
|
|
|
|
this.todo_ids = [];
|
|
|
|
|
|
|
|
this.cleanupWrapper = this.cleanup.bind(this);
|
|
|
|
document.addEventListener('beforeunload', this.cleanupWrapper);
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup() {
|
|
|
|
this.unbindEvents();
|
|
|
|
document.removeEventListener('beforeunload', this.cleanupWrapper);
|
|
|
|
}
|
|
|
|
|
|
|
|
unbindEvents() {
|
2022-08-13 15:12:31 +05:30
|
|
|
document.querySelectorAll('.js-done-todo, .js-undo-todo, .js-add-todo').forEach((el) => {
|
|
|
|
el.removeEventListener('click', this.updateRowStateClickedWrapper);
|
|
|
|
});
|
|
|
|
document.querySelectorAll('.js-todos-mark-all, .js-todos-undo-all').forEach((el) => {
|
|
|
|
el.removeEventListener('click', this.updateallStateClickedWrapper);
|
|
|
|
});
|
2017-08-17 22:00:37 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
bindEvents() {
|
|
|
|
this.updateRowStateClickedWrapper = this.updateRowStateClicked.bind(this);
|
|
|
|
this.updateAllStateClickedWrapper = this.updateAllStateClicked.bind(this);
|
|
|
|
|
2022-08-13 15:12:31 +05:30
|
|
|
document.querySelectorAll('.js-done-todo, .js-undo-todo, .js-add-todo').forEach((el) => {
|
|
|
|
el.addEventListener('click', this.updateRowStateClickedWrapper);
|
|
|
|
});
|
|
|
|
document.querySelectorAll('.js-todos-mark-all, .js-todos-undo-all').forEach((el) => {
|
|
|
|
el.addEventListener('click', this.updateAllStateClickedWrapper);
|
|
|
|
});
|
2017-08-17 22:00:37 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
initFilters() {
|
2021-04-29 21:17:54 +05:30
|
|
|
this.initAjaxFilterDropdown(getGroups, $('.js-group-search'), 'group_id');
|
|
|
|
this.initAjaxFilterDropdown(getProjects, $('.js-project-search'), 'project_id');
|
2017-08-17 22:00:37 +05:30
|
|
|
this.initFilterDropdown($('.js-type-search'), 'type');
|
|
|
|
this.initFilterDropdown($('.js-action-search'), 'action_id');
|
|
|
|
|
|
|
|
return new UsersSelect();
|
|
|
|
}
|
|
|
|
|
2021-04-29 21:17:54 +05:30
|
|
|
initAjaxFilterDropdown(apiMethod, $dropdown, fieldName) {
|
|
|
|
initDeprecatedJQueryDropdown($dropdown, {
|
|
|
|
fieldName,
|
|
|
|
selectable: true,
|
|
|
|
filterable: true,
|
|
|
|
filterRemote: true,
|
|
|
|
data(search, callback) {
|
|
|
|
return apiMethod(search, {}, (data) => {
|
|
|
|
callback(
|
|
|
|
data.map((d) => ({
|
|
|
|
id: d.id,
|
|
|
|
text: d.full_name || d.name_with_namespace,
|
|
|
|
})),
|
|
|
|
);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
clicked: () => {
|
|
|
|
const $formEl = $dropdown.closest('form.filter-form');
|
|
|
|
$formEl.submit();
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-08-17 22:00:37 +05:30
|
|
|
initFilterDropdown($dropdown, fieldName, searchFields) {
|
2020-11-24 15:15:51 +05:30
|
|
|
initDeprecatedJQueryDropdown($dropdown, {
|
2017-08-17 22:00:37 +05:30
|
|
|
fieldName,
|
|
|
|
selectable: true,
|
2021-12-11 22:18:48 +05:30
|
|
|
filterable: Boolean(searchFields),
|
2017-08-17 22:00:37 +05:30
|
|
|
search: { fields: searchFields },
|
|
|
|
data: $dropdown.data('data'),
|
2018-11-18 11:00:15 +05:30
|
|
|
clicked: () => {
|
|
|
|
const $formEl = $dropdown.closest('form.filter-form');
|
|
|
|
$formEl.submit();
|
|
|
|
},
|
2017-08-17 22:00:37 +05:30
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
updateRowStateClicked(e) {
|
2017-09-10 17:25:29 +05:30
|
|
|
e.stopPropagation();
|
2017-08-17 22:00:37 +05:30
|
|
|
e.preventDefault();
|
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
let { currentTarget } = e;
|
|
|
|
if (currentTarget.tagName === 'svg' || currentTarget.tagName === 'use') {
|
|
|
|
currentTarget = currentTarget.closest('a');
|
|
|
|
}
|
|
|
|
currentTarget.setAttribute('disabled', true);
|
|
|
|
currentTarget.classList.add('disabled');
|
2018-03-17 18:26:18 +05:30
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
currentTarget.querySelector('.js-todo-button-icon').classList.add('hidden');
|
2022-05-07 20:08:51 +05:30
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
axios[currentTarget.dataset.method](currentTarget.href)
|
2018-03-17 18:26:18 +05:30
|
|
|
.then(({ data }) => {
|
2023-03-04 22:38:38 +05:30
|
|
|
this.updateRowState(currentTarget);
|
2018-03-17 18:26:18 +05:30
|
|
|
this.updateBadges(data);
|
2018-12-13 13:39:08 +05:30
|
|
|
})
|
|
|
|
.catch(() => {
|
2023-03-04 22:38:38 +05:30
|
|
|
this.updateRowState(currentTarget, true);
|
2022-11-25 23:54:43 +05:30
|
|
|
return createAlert({
|
2021-09-30 23:02:18 +05:30
|
|
|
message: __('Error updating status of to-do item.'),
|
|
|
|
});
|
2018-12-05 23:21:45 +05:30
|
|
|
});
|
2017-08-17 22:00:37 +05:30
|
|
|
}
|
|
|
|
|
2018-12-05 23:21:45 +05:30
|
|
|
updateRowState(target, isInactive = false) {
|
2017-08-17 22:00:37 +05:30
|
|
|
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');
|
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
target.querySelector('.js-todo-button-icon').classList.remove('hidden');
|
2022-05-07 20:08:51 +05:30
|
|
|
|
2018-12-05 23:21:45 +05:30
|
|
|
if (isInactive === true) {
|
|
|
|
restoreBtn.classList.add('hidden');
|
|
|
|
doneBtn.classList.remove('hidden');
|
|
|
|
} else if (target === doneBtn) {
|
2023-04-23 21:23:45 +05:30
|
|
|
row.classList.add('done-reversible', 'gl-bg-gray-10', 'gl-border-gray-50');
|
2017-08-17 22:00:37 +05:30
|
|
|
restoreBtn.classList.remove('hidden');
|
|
|
|
} else if (target === restoreBtn) {
|
2023-04-23 21:23:45 +05:30
|
|
|
row.classList.remove('done-reversible', 'gl-bg-gray-10', 'gl-border-gray-50');
|
2017-08-17 22:00:37 +05:30
|
|
|
doneBtn.classList.remove('hidden');
|
|
|
|
} else {
|
|
|
|
row.parentNode.removeChild(row);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
updateAllStateClicked(e) {
|
2017-09-10 17:25:29 +05:30
|
|
|
e.stopPropagation();
|
2017-08-17 22:00:37 +05:30
|
|
|
e.preventDefault();
|
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
const { currentTarget } = e;
|
|
|
|
currentTarget.setAttribute('disabled', true);
|
|
|
|
currentTarget.classList.add('disabled');
|
2018-03-17 18:26:18 +05:30
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
currentTarget.querySelector('.gl-spinner-container').classList.add('gl-mr-2');
|
2022-05-07 20:08:51 +05:30
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
axios[currentTarget.dataset.method](currentTarget.href, {
|
2018-03-17 18:26:18 +05:30
|
|
|
ids: this.todo_ids,
|
2018-12-13 13:39:08 +05:30
|
|
|
})
|
|
|
|
.then(({ data }) => {
|
2023-04-23 21:23:45 +05:30
|
|
|
this.updateAllState(currentTarget, data);
|
2018-12-13 13:39:08 +05:30
|
|
|
this.updateBadges(data);
|
|
|
|
})
|
2021-09-30 23:02:18 +05:30
|
|
|
.catch(() =>
|
2022-11-25 23:54:43 +05:30
|
|
|
createAlert({
|
2021-09-30 23:02:18 +05:30
|
|
|
message: __('Error updating status for all to-do items.'),
|
|
|
|
}),
|
|
|
|
);
|
2017-08-17 22:00:37 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
updateAllState(target, data) {
|
|
|
|
const markAllDoneBtn = document.querySelector('.js-todos-mark-all');
|
|
|
|
const undoAllBtn = document.querySelector('.js-todos-undo-all');
|
|
|
|
const todoListContainer = document.querySelector('.js-todos-list-container');
|
|
|
|
const nothingHereContainer = document.querySelector('.js-nothing-here-container');
|
|
|
|
|
|
|
|
target.removeAttribute('disabled');
|
|
|
|
target.classList.remove('disabled');
|
|
|
|
|
2022-05-07 20:08:51 +05:30
|
|
|
target.querySelector('.gl-spinner-container').classList.remove('gl-mr-2');
|
|
|
|
|
2018-12-13 13:39:08 +05:30
|
|
|
this.todo_ids = target === markAllDoneBtn ? data.updated_ids : [];
|
2017-08-17 22:00:37 +05:30
|
|
|
undoAllBtn.classList.toggle('hidden');
|
|
|
|
markAllDoneBtn.classList.toggle('hidden');
|
|
|
|
todoListContainer.classList.toggle('hidden');
|
|
|
|
nothingHereContainer.classList.toggle('hidden');
|
|
|
|
}
|
|
|
|
|
|
|
|
updateBadges(data) {
|
2022-08-13 15:12:31 +05:30
|
|
|
const event = new CustomEvent('todo:toggle', {
|
|
|
|
detail: {
|
|
|
|
count: data.count,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
document.dispatchEvent(event);
|
2022-10-11 01:57:18 +05:30
|
|
|
// eslint-disable-next-line no-unsanitized/property
|
2022-03-02 08:16:31 +05:30
|
|
|
document.querySelector('.js-todos-pending .js-todos-badge').innerHTML = addDelimiter(
|
|
|
|
data.count,
|
|
|
|
);
|
2022-10-11 01:57:18 +05:30
|
|
|
// eslint-disable-next-line no-unsanitized/property
|
2022-03-02 08:16:31 +05:30
|
|
|
document.querySelector('.js-todos-done .js-todos-badge').innerHTML = addDelimiter(
|
|
|
|
data.done_count,
|
|
|
|
);
|
2017-08-17 22:00:37 +05:30
|
|
|
}
|
|
|
|
}
|