Example #1
0
 setRepoRadio() {
   const multiEditRadios = $('input[name="user[multi_file]"]');
   if (parseBoolean(this.newRepoActivated)) {
     multiEditRadios.filter('[value=on]').prop('checked', true);
   } else {
     multiEditRadios.filter('[value=off]').prop('checked', true);
   }
 }
Example #2
0
  render() {
    if (!this.$sidebar.length) return;

    const breakpoint = bp.getBreakpointSize();

    if (breakpoint === 'sm' || breakpoint === 'md') {
      this.toggleCollapsedSidebar(true, false);
    } else if (breakpoint === 'lg') {
      const collapse = parseBoolean(Cookies.get('sidebar_collapsed'));
      this.toggleCollapsedSidebar(collapse, false);
    }
  }
Example #3
0
      title: 'Welcome to your Issue Board!',
      position: 0,
    });

    this.state.lists = _.sortBy(this.state.lists, 'position');
  },
  removeBlankState() {
    this.removeList('blank');

    Cookies.set('issue_board_welcome_hidden', 'true', {
      expires: 365 * 10,
      path: '',
    });
  },
  welcomeIsHidden() {
    return parseBoolean(Cookies.get('issue_board_welcome_hidden'));
  },
  removeList(id, type = 'blank') {
    const list = this.findList('id', id, type);

    if (!list) return;

    this.state.lists = this.state.lists.filter(list => list.id !== id);
  },
  moveList(listFrom, orderLists) {
    orderLists.forEach((id, i) => {
      const list = this.findList('id', parseInt(id, 10));

      list.position = i;
    });
    listFrom.update();
Example #4
0
export default (containerId = 'js-groups-tree', endpoint, action = '') => {
  const containerEl = document.getElementById(containerId);
  let dataEl;

  // Don't do anything if element doesn't exist (No groups)
  // This is for when the user enters directly to the page via URL
  if (!containerEl) {
    return;
  }

  const el = action ? containerEl.querySelector(GROUPS_LIST_HOLDER_CLASS) : containerEl;

  if (action) {
    dataEl = containerEl.querySelector(CONTENT_LIST_CLASS);
  }

  Vue.component('group-folder', groupFolderComponent);
  Vue.component('group-item', groupItemComponent);

  // eslint-disable-next-line no-new
  new Vue({
    el,
    components: {
      groupsApp,
    },
    data() {
      const { dataset } = dataEl || this.$options.el;
      const hideProjects = parseBoolean(dataset.hideProjects);
      const service = new GroupsService(endpoint || dataset.endpoint);
      const store = new GroupsStore(hideProjects);

      return {
        action,
        store,
        service,
        hideProjects,
        loading: true,
        containerId,
      };
    },
    beforeMount() {
      if (this.action) {
        return;
      }

      const { dataset } = dataEl || this.$options.el;
      let groupFilterList = null;
      const form = document.querySelector(dataset.formSel);
      const filter = document.querySelector(dataset.filterSel);
      const holder = document.querySelector(dataset.holderSel);

      const opts = {
        form,
        filter,
        holder,
        filterEndpoint: endpoint || dataset.endpoint,
        pagePath: dataset.path,
        dropdownSel: dataset.dropdownSel,
        filterInputField: 'filter',
        action: this.action,
      };

      groupFilterList = new GroupFilterableList(opts);
      groupFilterList.initSearch();
    },
    render(createElement) {
      return createElement('groups-app', {
        props: {
          action: this.action,
          store: this.store,
          service: this.service,
          hideProjects: this.hideProjects,
          containerId: this.containerId,
        },
      });
    },
  });
};
Example #5
0
export default () => {
  const $boardApp = document.getElementById('board-app');

  // check for browser back and trigger a hard reload to circumvent browser caching.
  window.addEventListener('pageshow', event => {
    const isNavTypeBackForward =
      window.performance && window.performance.navigation.type === NavigationType.TYPE_BACK_FORWARD;

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

  if (issueBoardsApp) {
    issueBoardsApp.$destroy(true);
  }

  boardsStore.create();

  issueBoardsApp = new Vue({
    el: $boardApp,
    components: {
      Board,
      BoardSidebar,
      BoardAddIssuesModal,
    },
    data: {
      state: boardsStore.state,
      loading: true,
      boardsEndpoint: $boardApp.dataset.boardsEndpoint,
      recentBoardsEndpoint: $boardApp.dataset.recentBoardsEndpoint,
      listsEndpoint: $boardApp.dataset.listsEndpoint,
      boardId: $boardApp.dataset.boardId,
      disabled: parseBoolean($boardApp.dataset.disabled),
      issueLinkBase: $boardApp.dataset.issueLinkBase,
      rootPath: $boardApp.dataset.rootPath,
      bulkUpdatePath: $boardApp.dataset.bulkUpdatePath,
      detailIssue: boardsStore.detail,
      defaultAvatar: $boardApp.dataset.defaultAvatar,
    },
    computed: {
      detailIssueVisible() {
        return Object.keys(this.detailIssue.issue).length;
      },
    },
    created() {
      gl.boardService = new BoardService({
        boardsEndpoint: this.boardsEndpoint,
        recentBoardsEndpoint: this.recentBoardsEndpoint,
        listsEndpoint: this.listsEndpoint,
        bulkUpdatePath: this.bulkUpdatePath,
        boardId: this.boardId,
      });
      boardsStore.rootPath = this.boardsEndpoint;

      eventHub.$on('updateTokens', this.updateTokens);
      eventHub.$on('newDetailIssue', this.updateDetailIssue);
      eventHub.$on('clearDetailIssue', this.clearDetailIssue);
      sidebarEventHub.$on('toggleSubscription', this.toggleSubscription);
    },
    beforeDestroy() {
      eventHub.$off('updateTokens', this.updateTokens);
      eventHub.$off('newDetailIssue', this.updateDetailIssue);
      eventHub.$off('clearDetailIssue', this.clearDetailIssue);
      sidebarEventHub.$off('toggleSubscription', this.toggleSubscription);
    },
    mounted() {
      this.filterManager = new FilteredSearchBoards(boardsStore.filter, true, boardsStore.cantEdit);
      this.filterManager.setup();

      boardsStore.disabled = this.disabled;
      gl.boardService
        .all()
        .then(res => res.data)
        .then(data => {
          data.forEach(board => {
            const list = boardsStore.addList(board, this.defaultAvatar);

            if (list.type === 'closed') {
              list.position = Infinity;
            } else if (list.type === 'backlog') {
              list.position = -1;
            }
          });

          this.state.lists = _.sortBy(this.state.lists, 'position');

          boardsStore.addBlankState();
          this.loading = false;
        })
        .catch(() => {
          Flash('An error occurred while fetching the board lists. Please try again.');
        });
    },
    methods: {
      updateTokens() {
        this.filterManager.updateTokens();
      },
      updateDetailIssue(newIssue) {
        const { sidebarInfoEndpoint } = newIssue;
        if (sidebarInfoEndpoint && newIssue.subscribed === undefined) {
          newIssue.setFetchingState('subscriptions', true);
          BoardService.getIssueInfo(sidebarInfoEndpoint)
            .then(res => res.data)
            .then(data => {
              newIssue.setFetchingState('subscriptions', false);
              newIssue.updateData({
                subscribed: data.subscribed,
              });
            })
            .catch(() => {
              newIssue.setFetchingState('subscriptions', false);
              Flash(__('An error occurred while fetching sidebar data'));
            });
        }

        boardsStore.detail.issue = newIssue;
      },
      clearDetailIssue() {
        boardsStore.detail.issue = {};
      },
      toggleSubscription(id) {
        const { issue } = boardsStore.detail;
        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'));
            });
        }
      },
    },
  });

  // eslint-disable-next-line no-new
  new Vue({
    el: document.getElementById('js-add-list'),
    data: {
      filters: boardsStore.state.filters,
    },
    mounted() {
      initNewListDropdown();
    },
  });

  const issueBoardsModal = document.getElementById('js-add-issues-btn');

  if (issueBoardsModal) {
    // eslint-disable-next-line no-new
    new Vue({
      el: issueBoardsModal,
      mixins: [modalMixin],
      data() {
        return {
          modal: ModalStore.store,
          store: boardsStore.state,
          canAdminList: this.$options.el.hasAttribute('data-can-admin-list'),
        };
      },
      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';
          }

          return '';
        },
      },
      watch: {
        disabled() {
          this.updateTooltip();
        },
      },
      mounted() {
        this.updateTooltip();
      },
      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);
          }
        },
      },
      template: `
        <div class="board-extra-actions">
          <button
            class="btn btn-success prepend-left-10"
            type="button"
            data-placement="bottom"
            ref="addIssuesButton"
            :class="{ 'disabled': disabled }"
            :title="tooltipTitle"
            :aria-disabled="disabled"
            v-if="canAdminList"
            @click="openModal">
            Add issues
          </button>
        </div>
      `,
    });
  }
};