From 4c1e1ab1d7da1716fd6db2111a5a7e37dac799cd Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Mon, 8 Jan 2018 21:55:28 +0000 Subject: Refactor dashboard todos inside dispatcher --- app/assets/javascripts/dispatcher.js | 6 +- .../pages/dashboard/todos/index/index.js | 3 + .../pages/dashboard/todos/index/todos.js | 156 +++++++++++++++++++++ app/assets/javascripts/todos.js | 156 --------------------- spec/javascripts/todos_spec.js | 2 +- 5 files changed, 163 insertions(+), 160 deletions(-) create mode 100644 app/assets/javascripts/pages/dashboard/todos/index/index.js create mode 100644 app/assets/javascripts/pages/dashboard/todos/index/todos.js delete mode 100644 app/assets/javascripts/todos.js diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index 42f61d33f6e..9e8b2acfe1b 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -56,7 +56,6 @@ import GfmAutoComplete from './gfm_auto_complete'; import ShortcutsBlob from './shortcuts_blob'; import SigninTabsMemoizer from './signin_tabs_memoizer'; import Star from './star'; -import Todos from './todos'; import TreeView from './tree'; import UsagePing from './usage_ping'; import UsernameValidator from './username_validator'; @@ -111,6 +110,7 @@ import Activities from './activities'; } const fail = () => Flash('Error loading dynamic module'); + const callDefault = m => m.default(); path = page.split(':'); shortcut_handler = null; @@ -212,7 +212,7 @@ import Activities from './activities'; projectSelect(); break; case 'dashboard:todos:index': - new Todos(); + import('./pages/dashboard/todos/index').then(callDefault).catch(fail); break; case 'dashboard:projects:index': case 'dashboard:projects:starred': @@ -542,7 +542,7 @@ import Activities from './activities'; new CILintEditor(); break; case 'users:show': - import('./pages/users/show').then(m => m.default()).catch(fail); + import('./pages/users/show').then(callDefault).catch(fail); break; case 'admin:conversational_development_index:show': new UserCallout(); 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); + } + } +} diff --git a/app/assets/javascripts/todos.js b/app/assets/javascripts/todos.js deleted file mode 100644 index 748caecf153..00000000000 --- a/app/assets/javascripts/todos.js +++ /dev/null @@ -1,156 +0,0 @@ -/* 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); - } - } -} diff --git a/spec/javascripts/todos_spec.js b/spec/javascripts/todos_spec.js index 59e16f0786e..35871dddf89 100644 --- a/spec/javascripts/todos_spec.js +++ b/spec/javascripts/todos_spec.js @@ -1,5 +1,5 @@ import * as urlUtils from '~/lib/utils/url_utility'; -import Todos from '~/todos'; +import Todos from '~/pages/dashboard/todos/index/todos'; import '~/lib/utils/common_utils'; describe('Todos', () => { -- cgit v1.2.1