index.js 8.2 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 boardsStore from './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
import './filters/due_date_filters';
22 23 24
import Board from './components/board';
import BoardSidebar from './components/board_sidebar';
import initNewListDropdown from './components/new_list_dropdown';
25
import BoardAddIssuesModal from './components/modal/index.vue';
M
Mike Greiling 已提交
26
import '~/vue_shared/vue_resource_interceptor';
27 28 29 30 31
import {
  NavigationType,
  convertObjectPropsToCamelCase,
  parseBoolean,
} from '~/lib/utils/common_utils';
P
Phil Hughes 已提交
32

33 34
let issueBoardsApp;

C
Constance Okoghenun 已提交
35
export default () => {
36
  const $boardApp = document.getElementById('board-app');
P
Phil Hughes 已提交
37

38
  // check for browser back and trigger a hard reload to circumvent browser caching.
39 40 41
  window.addEventListener('pageshow', event => {
    const isNavTypeBackForward =
      window.performance && window.performance.navigation.type === NavigationType.TYPE_BACK_FORWARD;
42 43 44 45 46 47

    if (event.persisted || isNavTypeBackForward) {
      window.location.reload();
    }
  });

48 49
  if (issueBoardsApp) {
    issueBoardsApp.$destroy(true);
50 51
  }

52
  boardsStore.create();
53

54
  issueBoardsApp = new Vue({
55
    el: $boardApp,
56
    components: {
57 58
      Board,
      BoardSidebar,
59
      BoardAddIssuesModal,
60
    },
P
Phil Hughes 已提交
61
    data: {
62
      state: boardsStore.state,
P
Phil Hughes 已提交
63
      loading: true,
64
      boardsEndpoint: $boardApp.dataset.boardsEndpoint,
65
      recentBoardsEndpoint: $boardApp.dataset.recentBoardsEndpoint,
66
      listsEndpoint: $boardApp.dataset.listsEndpoint,
67
      boardId: $boardApp.dataset.boardId,
68
      disabled: parseBoolean($boardApp.dataset.disabled),
69
      issueLinkBase: $boardApp.dataset.issueLinkBase,
70
      rootPath: $boardApp.dataset.rootPath,
71
      bulkUpdatePath: $boardApp.dataset.bulkUpdatePath,
72
      detailIssue: boardsStore.detail,
73
      defaultAvatar: $boardApp.dataset.defaultAvatar,
P
Phil Hughes 已提交
74
    },
75
    computed: {
P
Phil Hughes 已提交
76
      detailIssueVisible() {
77
        return Object.keys(this.detailIssue.issue).length;
78
      },
79
    },
P
Phil Hughes 已提交
80
    created() {
81 82
      gl.boardService = new BoardService({
        boardsEndpoint: this.boardsEndpoint,
83
        recentBoardsEndpoint: this.recentBoardsEndpoint,
84 85 86 87
        listsEndpoint: this.listsEndpoint,
        bulkUpdatePath: this.bulkUpdatePath,
        boardId: this.boardId,
      });
88
      boardsStore.rootPath = this.boardsEndpoint;
P
Phil Hughes 已提交
89

90
      eventHub.$on('updateTokens', this.updateTokens);
91 92 93
      eventHub.$on('newDetailIssue', this.updateDetailIssue);
      eventHub.$on('clearDetailIssue', this.clearDetailIssue);
      sidebarEventHub.$on('toggleSubscription', this.toggleSubscription);
P
Phil Hughes 已提交
94 95
    },
    beforeDestroy() {
96
      eventHub.$off('updateTokens', this.updateTokens);
97 98 99
      eventHub.$off('newDetailIssue', this.updateDetailIssue);
      eventHub.$off('clearDetailIssue', this.clearDetailIssue);
      sidebarEventHub.$off('toggleSubscription', this.toggleSubscription);
100
    },
P
Phil Hughes 已提交
101
    mounted() {
102
      this.filterManager = new FilteredSearchBoards(boardsStore.filter, true, boardsStore.cantEdit);
103 104
      this.filterManager.setup();

105
      boardsStore.disabled = this.disabled;
P
Phil Hughes 已提交
106 107
      gl.boardService
        .all()
E
Eric Eastwood 已提交
108
        .then(res => res.data)
P
Phil Hughes 已提交
109 110
        .then(data => {
          data.forEach(board => {
111
            const list = boardsStore.addList(board, this.defaultAvatar);
112

113
            if (list.type === 'closed') {
P
Phil Hughes 已提交
114
              list.position = Infinity;
115 116
            } else if (list.type === 'backlog') {
              list.position = -1;
117
            }
P
Phil Hughes 已提交
118
          });
119

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

122
          boardsStore.addBlankState();
123
          this.loading = false;
F
Filipa Lacerda 已提交
124
        })
E
Eric Eastwood 已提交
125
        .catch(() => {
126
          Flash(__('An error occurred while fetching the board lists. Please try again.'));
E
Eric Eastwood 已提交
127
        });
P
Phil Hughes 已提交
128 129 130 131
    },
    methods: {
      updateTokens() {
        this.filterManager.updateTokens();
132 133
      },
      updateDetailIssue(newIssue) {
134
        const { sidebarInfoEndpoint } = newIssue;
135 136 137
        if (sidebarInfoEndpoint && newIssue.subscribed === undefined) {
          newIssue.setFetchingState('subscriptions', true);
          BoardService.getIssueInfo(sidebarInfoEndpoint)
E
Eric Eastwood 已提交
138
            .then(res => res.data)
P
Phil Hughes 已提交
139
            .then(data => {
140 141 142 143 144 145 146 147 148 149
              const {
                subscribed,
                totalTimeSpent,
                timeEstimate,
                humanTimeEstimate,
                humanTotalTimeSpent,
                weight,
                epic,
              } = convertObjectPropsToCamelCase(data);

150 151
              newIssue.setFetchingState('subscriptions', false);
              newIssue.updateData({
152 153 154 155 156 157 158
                humanTimeSpent: humanTotalTimeSpent,
                timeSpent: totalTimeSpent,
                humanTimeEstimate,
                timeEstimate,
                subscribed,
                weight,
                epic,
159 160 161 162 163 164 165 166
              });
            })
            .catch(() => {
              newIssue.setFetchingState('subscriptions', false);
              Flash(__('An error occurred while fetching sidebar data'));
            });
        }

167
        boardsStore.detail.issue = newIssue;
168 169
      },
      clearDetailIssue() {
170
        boardsStore.detail.issue = {};
171 172
      },
      toggleSubscription(id) {
173
        const { issue } = boardsStore.detail;
174 175 176 177 178 179 180 181 182 183 184 185 186 187
        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 已提交
188
      },
P
Phil Hughes 已提交
189
    },
P
Phil Hughes 已提交
190
  });
191

192 193
  // eslint-disable-next-line no-new
  new Vue({
P
Phil Hughes 已提交
194
    el: document.getElementById('js-add-list'),
195
    data: {
196
      filters: boardsStore.state.filters,
197
    },
P
Phil Hughes 已提交
198
    mounted() {
199
      initNewListDropdown();
200
    },
201
  });
P
Phil Hughes 已提交
202

P
Phil Hughes 已提交
203 204 205
  const issueBoardsModal = document.getElementById('js-add-issues-btn');

  if (issueBoardsModal) {
206 207
    // eslint-disable-next-line no-new
    new Vue({
P
Phil Hughes 已提交
208 209 210 211 212
      el: issueBoardsModal,
      mixins: [modalMixin],
      data() {
        return {
          modal: ModalStore.store,
213
          store: boardsStore.state,
P
Phil Hughes 已提交
214 215
          canAdminList: this.$options.el.hasAttribute('data-can-admin-list'),
        };
216
      },
P
Phil Hughes 已提交
217 218 219 220 221 222 223 224 225
      computed: {
        disabled() {
          if (!this.store) {
            return true;
          }
          return !this.store.lists.filter(list => !list.preset).length;
        },
        tooltipTitle() {
          if (this.disabled) {
226
            return __('Please add a list to your board first');
P
Phil Hughes 已提交
227
          }
228

P
Phil Hughes 已提交
229 230
          return '';
        },
231
      },
P
Phil Hughes 已提交
232 233 234 235 236 237
      watch: {
        disabled() {
          this.updateTooltip();
        },
      },
      mounted() {
238 239
        this.updateTooltip();
      },
P
Phil Hughes 已提交
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
      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);
255
          }
P
Phil Hughes 已提交
256
        },
257
      },
P
Phil Hughes 已提交
258 259 260
      template: `
        <div class="board-extra-actions">
          <button
261
            class="btn btn-success prepend-left-10"
P
Phil Hughes 已提交
262 263 264 265 266 267 268 269 270 271 272 273 274 275
            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 已提交
276
};