summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/todos.js
blob: e9513725d9d882b0270ccb613b00eea0aac639ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/* eslint-disable class-methods-use-this, no-new, func-names, no-unneeded-ternary, object-shorthand, quote-props, no-param-reassign, max-len */
/* global UsersSelect */

((global) => {
  class Todos {
    constructor() {
      this.initFilters();
      this.bindEvents();

      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').off('click', this.updateStateClickedWrapper);
      $('.js-todos-mark-all').off('click', this.allDoneClickedWrapper);
      $('.todo').off('click', this.goToTodoUrl);
    }

    bindEvents() {
      this.updateStateClickedWrapper = this.updateStateClicked.bind(this);
      this.allDoneClickedWrapper = this.allDoneClicked.bind(this);

      $('.js-done-todo, .js-undo-todo').on('click', this.updateStateClickedWrapper);
      $('.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) {
        event.preventDefault();
        gl.utils.visitUrl(`${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();
        },
      });
    }

    updateStateClicked(e) {
      e.preventDefault();
      const target = e.target;
      target.setAttribute('disabled', '');
      target.classList.add('disabled');
      $.ajax({
        type: 'POST',
        url: target.getAttribute('href'),
        dataType: 'json',
        data: {
          '_method': target.getAttribute('data-method'),
        },
        success: (data) => {
          this.updateState(target);
          this.updateBadges(data);
        },
      });
    }

    allDoneClicked(e) {
      e.preventDefault();
      const $target = $(e.currentTarget);
      $target.disable();
      $.ajax({
        type: 'POST',
        url: $target.attr('href'),
        dataType: 'json',
        data: {
          '_method': 'delete',
        },
        success: (data) => {
          $target.remove();
          $('.js-todos-all').html('<div class="nothing-here-block">You\'re all done!</div>');
          this.updateBadges(data);
        },
      });
    }

    updateState(target) {
      const row = target.closest('li');
      const restoreBtn = row.querySelector('.js-undo-todo');
      const doneBtn = row.querySelector('.js-done-todo');

      target.removeAttribute('disabled');
      target.classList.remove('disabled');
      target.classList.add('hidden');

      if (target === doneBtn) {
        row.classList.add('done-reversible');
        restoreBtn.classList.remove('hidden');
      } else {
        row.classList.remove('done-reversible');
        doneBtn.classList.remove('hidden');
      }
    }

    updateBadges(data) {
      $(document).trigger('todo:toggle', data.count);
      $('.todos-pending .badge').text(data.count);
      $('.todos-done .badge').text(data.done_count);
    }

    goToTodoUrl(e) {
      const todoLink = this.dataset.url;

      if (!todoLink) {
        return;
      }

      if (gl.utils.isMetaClick(e)) {
        const windowTarget = '_blank';
        const selected = e.target;
        e.preventDefault();

        if (selected.tagName === 'IMG') {
          const avatarUrl = selected.parentElement.getAttribute('href');
          window.open(avatarUrl, windowTarget);
        } else {
          window.open(todoLink, windowTarget);
        }
      } else {
        gl.utils.visitUrl(todoLink);
      }
    }
  }

  global.Todos = Todos;
})(window.gl || (window.gl = {}));