summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/boards/components/modal/list.js.es6
blob: 309696c70788b1cbec4ee2a06ad7fd45c1311de8 (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
/* global Vue */
/* global ListIssue */
/* global Masonry */
(() => {
  let listMasonry;
  const ModalStore = gl.issueBoards.ModalStore;

  gl.issueBoards.ModalList = Vue.extend({
    props: [
      'issueLinkBase',
    ],
    data() {
      return ModalStore.store;
    },
    watch: {
      activeTab() {
        this.initMasonry();

        if (this.activeTab === 'all') {
          ModalStore.purgeUnselectedIssues();
        }
      },
      issues: {
        handler() {
          this.initMasonry();
        },
        deep: true,
      },
    },
    computed: {
      loopIssues() {
        if (this.activeTab === 'all') {
          return this.issues;
        }

        return this.selectedIssues;
      },
    },
    methods: {
      toggleIssue(e, issue) {
        if (e.target.tagName !== 'A') {
          ModalStore.toggleIssue(issue);
        }
      },
      listHeight() {
        return this.$refs.list.getBoundingClientRect().height;
      },
      scrollHeight() {
        return this.$refs.list.scrollHeight;
      },
      scrollTop() {
        return this.$refs.list.scrollTop + this.listHeight();
      },
      showIssue(issue) {
        if (this.activeTab === 'all') return true;

        const index = ModalStore.selectedIssueIndex(issue);

        return index !== -1;
      },
      initMasonry() {
        const listScrollTop = this.$refs.list.scrollTop;

        this.$nextTick(() => {
          this.destroyMasonry();
          listMasonry = new Masonry(this.$refs.list, {
            transitionDuration: 0,
          });

          this.$refs.list.scrollTop = listScrollTop;
        });
      },
      destroyMasonry() {
        if (listMasonry) {
          listMasonry.destroy();
          listMasonry = undefined;
        }
      },
    },
    mounted() {
      this.initMasonry();

      this.$refs.list.onscroll = () => {
        const currentPage = Math.floor(this.issues.length / this.perPage);

        if ((this.scrollTop() > this.scrollHeight() - 100) && !this.loadingNewPage
          && currentPage === this.page) {
          this.loadingNewPage = true;
          this.page += 1;
        }
      };
    },
    destroyed() {
      this.destroyMasonry();
    },
    components: {
      issueCardInner: gl.issueBoards.IssueCardInner,
    },
    template: `
      <div
        class="add-issues-list add-issues-list-columns"
        ref="list">
        <div
          v-for="issue in loopIssues"
          v-if="showIssue(issue)"
          class="card-parent">
          <div
            class="card"
            :class="{ 'is-active': issue.selected }"
            @click="toggleIssue($event, issue)">
            <issue-card-inner
              :issue="issue"
              :issue-link-base="issueLinkBase">
            </issue-card-inner>
            <span
              v-if="issue.selected"
              class="issue-card-selected text-center">
              <i class="fa fa-check"></i>
            </span>
          </div>
        </div>
      </div>
    `,
  });
})();