index.js 7.4 KB
Newer Older
1
import $ from 'jquery';
2
import _ from 'underscore';
M
Mike Greiling 已提交
3
import Vue from 'vue';
4 5 6

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

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

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

33
  window.gl = window.gl || {};
P
Phil Hughes 已提交
34

35 36 37 38
  if (gl.IssueBoardsApp) {
    gl.IssueBoardsApp.$destroy(true);
  }

39 40
  Store.create();

41 42 43 44
  // 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);

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

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

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

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

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

111
          Store.addBlankState();
112
          this.loading = false;
F
Filipa Lacerda 已提交
113
        })
E
Eric Eastwood 已提交
114 115 116
        .catch(() => {
          Flash('An error occurred while fetching the board lists. Please try again.');
        });
P
Phil Hughes 已提交
117 118 119 120
    },
    methods: {
      updateTokens() {
        this.filterManager.updateTokens();
121 122
      },
      updateDetailIssue(newIssue) {
123
        const { sidebarInfoEndpoint } = newIssue;
124 125 126
        if (sidebarInfoEndpoint && newIssue.subscribed === undefined) {
          newIssue.setFetchingState('subscriptions', true);
          BoardService.getIssueInfo(sidebarInfoEndpoint)
E
Eric Eastwood 已提交
127
            .then(res => res.data)
P
Phil Hughes 已提交
128
            .then(data => {
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
              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) {
146
        const { issue } = Store.detail;
147 148 149 150 151 152 153 154 155 156 157 158 159 160
        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 已提交
161
      },
P
Phil Hughes 已提交
162
    },
P
Phil Hughes 已提交
163
  });
164 165

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

P
Phil Hughes 已提交
175 176 177 178 179 180 181 182 183 184 185 186
  const issueBoardsModal = document.getElementById('js-add-issues-btn');

  if (issueBoardsModal) {
    gl.IssueBoardsModalAddBtn = new Vue({
      el: issueBoardsModal,
      mixins: [modalMixin],
      data() {
        return {
          modal: ModalStore.store,
          store: Store.state,
          canAdminList: this.$options.el.hasAttribute('data-can-admin-list'),
        };
187
      },
P
Phil Hughes 已提交
188 189 190 191 192 193 194 195 196 197 198
      computed: {
        disabled() {
          if (!this.store) {
            return true;
          }
          return !this.store.lists.filter(list => !list.preset).length;
        },
        tooltipTitle() {
          if (this.disabled) {
            return 'Please add a list to your board first';
          }
199

P
Phil Hughes 已提交
200 201
          return '';
        },
202
      },
P
Phil Hughes 已提交
203 204 205 206 207 208
      watch: {
        disabled() {
          this.updateTooltip();
        },
      },
      mounted() {
209 210
        this.updateTooltip();
      },
P
Phil Hughes 已提交
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
      methods: {
        updateTooltip() {
          const $tooltip = $(this.$refs.addIssuesButton);

          this.$nextTick(() => {
            if (this.disabled) {
              $tooltip.tooltip();
            } else {
              $tooltip.tooltip('dispose');
            }
          });
        },
        openModal() {
          if (!this.disabled) {
            this.toggleModal(true);
226
          }
P
Phil Hughes 已提交
227
        },
228
      },
P
Phil Hughes 已提交
229 230 231
      template: `
        <div class="board-extra-actions">
          <button
232
            class="btn btn-success prepend-left-10"
P
Phil Hughes 已提交
233 234 235 236 237 238 239 240 241 242 243 244 245 246
            type="button"
            data-placement="bottom"
            ref="addIssuesButton"
            :class="{ 'disabled': disabled }"
            :title="tooltipTitle"
            :aria-disabled="disabled"
            v-if="canAdminList"
            @click="openModal">
            Add issues
          </button>
        </div>
      `,
    });
  }
C
Constance Okoghenun 已提交
247
};