summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/pages/dashboard/todos
diff options
context:
space:
mode:
authorClement Ho <clemmakesapps@gmail.com>2018-01-08 21:55:28 +0000
committerJacob Schatz <jschatz@gitlab.com>2018-01-08 21:55:28 +0000
commit4c1e1ab1d7da1716fd6db2111a5a7e37dac799cd (patch)
tree7123f6ac0aca42bb1bc51fabfd8996449e582eb7 /app/assets/javascripts/pages/dashboard/todos
parent8a7bbe1ff3a384a21a837c8db82cc7c9613e3114 (diff)
downloadgitlab-ce-4c1e1ab1d7da1716fd6db2111a5a7e37dac799cd.tar.gz
Refactor dashboard todos inside dispatcher
Diffstat (limited to 'app/assets/javascripts/pages/dashboard/todos')
-rw-r--r--app/assets/javascripts/pages/dashboard/todos/index/index.js3
-rw-r--r--app/assets/javascripts/pages/dashboard/todos/index/todos.js156
2 files changed, 159 insertions, 0 deletions
diff --git a/app/assets/javascripts/pages/dashboard/todos/index/index.js b/app/assets/javascripts/pages/dashboard/todos/index/index.js
new file mode 100644
index 00000000000..77c23685943
--- /dev/null
+++ b/app/assets/javascripts/pages/dashboard/todos/index/index.js
@@ -0,0 +1,3 @@
+import Todos from './todos';
+
+export default () => new Todos();
diff --git a/app/assets/javascripts/pages/dashboard/todos/index/todos.js b/app/assets/javascripts/pages/dashboard/todos/index/todos.js
new file mode 100644
index 00000000000..e976a3d2f1d
--- /dev/null
+++ b/app/assets/javascripts/pages/dashboard/todos/index/todos.js
@@ -0,0 +1,156 @@
+/* eslint-disable class-methods-use-this, no-unneeded-ternary, quote-props */
+import { visitUrl } from '~/lib/utils/url_utility';
+import UsersSelect from '~/users_select';
+import { isMetaClick } from '~/lib/utils/common_utils';
+
+export default class Todos {
+ 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() {
+ $('.js-done-todo, .js-undo-todo, .js-add-todo').off('click', this.updateRowStateClickedWrapper);
+ $('.js-todos-mark-all', '.js-todos-undo-all').off('click', this.updateallStateClickedWrapper);
+ $('.todo').off('click', this.goToTodoUrl);
+ }
+
+ bindEvents() {
+ this.updateRowStateClickedWrapper = this.updateRowStateClicked.bind(this);
+ this.updateAllStateClickedWrapper = this.updateAllStateClicked.bind(this);
+
+ $('.js-done-todo, .js-undo-todo, .js-add-todo').on('click', this.updateRowStateClickedWrapper);
+ $('.js-todos-mark-all, .js-todos-undo-all').on('click', this.updateAllStateClickedWrapper);
+ $('.todo').on('click', this.goToTodoUrl);
+ }
+
+ initFilters() {
+ this.initFilterDropdown($('.js-project-search'), 'project_id', ['text']);
+ this.initFilterDropdown($('.js-type-search'), 'type');
+ this.initFilterDropdown($('.js-action-search'), 'action_id');
+
+ return new UsersSelect();
+ }
+
+ initFilterDropdown($dropdown, fieldName, searchFields) {
+ $dropdown.glDropdown({
+ fieldName,
+ selectable: true,
+ filterable: searchFields ? true : false,
+ search: { fields: searchFields },
+ data: $dropdown.data('data'),
+ clicked: () => $dropdown.closest('form.filter-form').submit(),
+ });
+ }
+
+ updateRowStateClicked(e) {
+ e.stopPropagation();
+ e.preventDefault();
+
+ const target = e.target;
+ target.setAttribute('disabled', true);
+ target.classList.add('disabled');
+ $.ajax({
+ type: 'POST',
+ url: target.dataset.href,
+ dataType: 'json',
+ data: {
+ '_method': target.dataset.method,
+ },
+ success: (data) => {
+ this.updateRowState(target);
+ return this.updateBadges(data);
+ },
+ });
+ }
+
+ 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');
+
+ if (target === doneBtn) {
+ row.classList.add('done-reversible');
+ restoreBtn.classList.remove('hidden');
+ } else if (target === restoreBtn) {
+ row.classList.remove('done-reversible');
+ doneBtn.classList.remove('hidden');
+ } else {
+ row.parentNode.removeChild(row);
+ }
+ }
+
+ updateAllStateClicked(e) {
+ e.stopPropagation();
+ e.preventDefault();
+
+ const target = e.currentTarget;
+ const requestData = { '_method': target.dataset.method, ids: this.todo_ids };
+ target.setAttribute('disabled', true);
+ target.classList.add('disabled');
+ $.ajax({
+ type: 'POST',
+ url: target.dataset.href,
+ dataType: 'json',
+ data: requestData,
+ success: (data) => {
+ this.updateAllState(target, data);
+ return this.updateBadges(data);
+ },
+ });
+ }
+
+ 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');
+
+ this.todo_ids = (target === markAllDoneBtn) ? data.updated_ids : [];
+ undoAllBtn.classList.toggle('hidden');
+ markAllDoneBtn.classList.toggle('hidden');
+ todoListContainer.classList.toggle('hidden');
+ nothingHereContainer.classList.toggle('hidden');
+ }
+
+ updateBadges(data) {
+ $(document).trigger('todo:toggle', data.count);
+ document.querySelector('.todos-pending .badge').innerHTML = data.count;
+ document.querySelector('.todos-done .badge').innerHTML = data.done_count;
+ }
+
+ goToTodoUrl(e) {
+ const todoLink = this.dataset.url;
+
+ if (!todoLink || e.target.tagName === 'A' || e.target.tagName === 'IMG') {
+ return;
+ }
+
+ e.stopPropagation();
+ e.preventDefault();
+
+ if (isMetaClick(e)) {
+ const windowTarget = '_blank';
+
+ window.open(todoLink, windowTarget);
+ } else {
+ visitUrl(todoLink);
+ }
+ }
+}