index.js 7.3 KB
Newer Older
1
/* eslint-disable quote-props, comma-dangle */
2

3
import $ from 'jquery';
4
import _ from 'underscore';
M
Mike Greiling 已提交
5
import Vue from 'vue';
6 7 8

import Flash from '~/flash';
import { __ } from '~/locale';
K
Kushal Pandya 已提交
9
import '~/vue_shared/models/label';
10
import '~/vue_shared/models/assignee';
11

12
import FilteredSearchBoards from './filtered_search_boards';
13
import eventHub from './eventhub';
14
import sidebarEventHub from '~/sidebar/event_hub'; // eslint-disable-line import/first
15 16 17
import './models/issue';
import './models/list';
import './models/milestone';
F
Felipe Artur 已提交
18
import './models/project';
19
import './stores/boards_store';
20
import ModalStore from './stores/modal_store';
21
import BoardService from './services/board_service';
22
import modalMixin from './mixins/modal_mixins';
23 24 25 26 27
import './mixins/sortable_default_options';
import './filters/due_date_filters';
import './components/board';
import './components/board_sidebar';
import './components/new_list_dropdown';
28
import BoardAddIssuesModal from './components/modal/index.vue';
29
import '~/vue_shared/vue_resource_interceptor'; // eslint-disable-line import/first
P
Phil Hughes 已提交
30

C
Constance Okoghenun 已提交
31
export default () => {
32 33
  const $boardApp = document.getElementById('board-app');
  const Store = gl.issueBoards.BoardsStore;
P
Phil Hughes 已提交
34

35
  window.gl = window.gl || {};
P
Phil Hughes 已提交
36

37 38 39 40
  if (gl.IssueBoardsApp) {
    gl.IssueBoardsApp.$destroy(true);
  }

41 42
  Store.create();

43 44 45 46
  // hack to allow sidebar scripts like milestone_select manipulate the BoardsStore
  gl.issueBoards.boardStoreIssueSet = (...args) => Vue.set(Store.detail.issue, ...args);
  gl.issueBoards.boardStoreIssueDelete = (...args) => Vue.delete(Store.detail.issue, ...args);

47
  gl.IssueBoardsApp = new Vue({
48
    el: $boardApp,
49
    components: {
P
Phil Hughes 已提交
50
      'board': gl.issueBoards.Board,
P
Phil Hughes 已提交
51
      'board-sidebar': gl.issueBoards.BoardSidebar,
52
      BoardAddIssuesModal,
53
    },
P
Phil Hughes 已提交
54
    data: {
55
      state: Store.state,
P
Phil Hughes 已提交
56
      loading: true,
57 58
      boardsEndpoint: $boardApp.dataset.boardsEndpoint,
      listsEndpoint: $boardApp.dataset.listsEndpoint,
59
      boardId: $boardApp.dataset.boardId,
60
      disabled: $boardApp.dataset.disabled === 'true',
61
      issueLinkBase: $boardApp.dataset.issueLinkBase,
62
      rootPath: $boardApp.dataset.rootPath,
63
      bulkUpdatePath: $boardApp.dataset.bulkUpdatePath,
64 65
      detailIssue: Store.detail,
      defaultAvatar: $boardApp.dataset.defaultAvatar,
P
Phil Hughes 已提交
66
    },
67 68 69
    computed: {
      detailIssueVisible () {
        return Object.keys(this.detailIssue.issue).length;
70
      },
71
    },
P
Phil Hughes 已提交
72
    created () {
73 74 75 76 77 78 79
      gl.boardService = new BoardService({
        boardsEndpoint: this.boardsEndpoint,
        listsEndpoint: this.listsEndpoint,
        bulkUpdatePath: this.bulkUpdatePath,
        boardId: this.boardId,
      });
      Store.rootPath = this.boardsEndpoint;
P
Phil Hughes 已提交
80

81
      eventHub.$on('updateTokens', this.updateTokens);
82 83 84
      eventHub.$on('newDetailIssue', this.updateDetailIssue);
      eventHub.$on('clearDetailIssue', this.clearDetailIssue);
      sidebarEventHub.$on('toggleSubscription', this.toggleSubscription);
P
Phil Hughes 已提交
85 86
    },
    beforeDestroy() {
87
      eventHub.$off('updateTokens', this.updateTokens);
88 89 90
      eventHub.$off('newDetailIssue', this.updateDetailIssue);
      eventHub.$off('clearDetailIssue', this.clearDetailIssue);
      sidebarEventHub.$off('toggleSubscription', this.toggleSubscription);
91
    },
F
Fatih Acet 已提交
92
    mounted () {
F
Felipe Artur 已提交
93
      this.filterManager = new FilteredSearchBoards(Store.filter, true, Store.cantEdit);
94 95
      this.filterManager.setup();

96
      Store.disabled = this.disabled;
97
      gl.boardService.all()
E
Eric Eastwood 已提交
98 99 100
        .then(res => res.data)
        .then((data) => {
          data.forEach((board) => {
101
            const list = Store.addList(board, this.defaultAvatar);
102

103
            if (list.type === 'closed') {
P
Phil Hughes 已提交
104
              list.position = Infinity;
105 106
            } else if (list.type === 'backlog') {
              list.position = -1;
107
            }
P
Phil Hughes 已提交
108
          });
109

P
Phil Hughes 已提交
110 111
          this.state.lists = _.sortBy(this.state.lists, 'position');

112
          Store.addBlankState();
113
          this.loading = false;
F
Filipa Lacerda 已提交
114
        })
E
Eric Eastwood 已提交
115 116 117
        .catch(() => {
          Flash('An error occurred while fetching the board lists. Please try again.');
        });
P
Phil Hughes 已提交
118 119 120 121
    },
    methods: {
      updateTokens() {
        this.filterManager.updateTokens();
122 123
      },
      updateDetailIssue(newIssue) {
124
        const { sidebarInfoEndpoint } = newIssue;
125 126 127
        if (sidebarInfoEndpoint && newIssue.subscribed === undefined) {
          newIssue.setFetchingState('subscriptions', true);
          BoardService.getIssueInfo(sidebarInfoEndpoint)
E
Eric Eastwood 已提交
128
            .then(res => res.data)
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
            .then((data) => {
              newIssue.setFetchingState('subscriptions', false);
              newIssue.updateData({
                subscribed: data.subscribed,
              });
            })
            .catch(() => {
              newIssue.setFetchingState('subscriptions', false);
              Flash(__('An error occurred while fetching sidebar data'));
            });
        }

        Store.detail.issue = newIssue;
      },
      clearDetailIssue() {
        Store.detail.issue = {};
      },
      toggleSubscription(id) {
147
        const { issue } = Store.detail;
148 149 150 151 152 153 154 155 156 157 158 159 160 161
        if (issue.id === id && issue.toggleSubscriptionEndpoint) {
          issue.setFetchingState('subscriptions', true);
          BoardService.toggleIssueSubscription(issue.toggleSubscriptionEndpoint)
            .then(() => {
              issue.setFetchingState('subscriptions', false);
              issue.updateData({
                subscribed: !issue.subscribed,
              });
            })
            .catch(() => {
              issue.setFetchingState('subscriptions', false);
              Flash(__('An error occurred when toggling the notification subscription'));
            });
        }
P
Phil Hughes 已提交
162 163
      }
    },
P
Phil Hughes 已提交
164
  });
165 166

  gl.IssueBoardsSearch = new Vue({
P
Phil Hughes 已提交
167
    el: document.getElementById('js-add-list'),
168
    data: {
169
      filters: Store.state.filters,
170 171 172
    },
    mounted () {
      gl.issueBoards.newListDropdownInit();
173
    },
174
  });
P
Phil Hughes 已提交
175

176
  gl.IssueBoardsModalAddBtn = new Vue({
177
    el: document.getElementById('js-add-issues-btn'),
178
    mixins: [modalMixin],
179 180 181 182
    data() {
      return {
        modal: ModalStore.store,
        store: Store.state,
F
Felipe Artur 已提交
183
        canAdminList: this.$options.el.hasAttribute('data-can-admin-list'),
184
      };
185 186 187
    },
    computed: {
      disabled() {
188 189 190
        if (!this.store) {
          return true;
        }
P
Phil Hughes 已提交
191
        return !this.store.lists.filter(list => !list.preset).length;
192
      },
193 194 195 196 197 198 199 200
      tooltipTitle() {
        if (this.disabled) {
          return 'Please add a list to your board first';
        }

        return '';
      },
    },
201 202 203 204 205 206 207 208
    watch: {
      disabled() {
        this.updateTooltip();
      },
    },
    mounted() {
      this.updateTooltip();
    },
209 210
    methods: {
      updateTooltip() {
211
        const $tooltip = $(this.$refs.addIssuesButton);
212 213 214 215 216

        this.$nextTick(() => {
          if (this.disabled) {
            $tooltip.tooltip();
          } else {
217
            $tooltip.tooltip('dispose');
218 219 220 221 222 223 224 225 226
          }
        });
      },
      openModal() {
        if (!this.disabled) {
          this.toggleModal(true);
        }
      },
    },
227
    template: `
228 229 230 231 232 233 234 235 236
      <div class="board-extra-actions">
        <button
          class="btn btn-create prepend-left-10"
          type="button"
          data-placement="bottom"
          ref="addIssuesButton"
          :class="{ 'disabled': disabled }"
          :title="tooltipTitle"
          :aria-disabled="disabled"
F
Felipe Artur 已提交
237
          v-if="canAdminList"
238 239 240 241
          @click="openModal">
          Add issues
        </button>
      </div>
242 243
    `,
  });
C
Constance Okoghenun 已提交
244
};