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); } }
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); } }
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();
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, }, }); }, }); };
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> `, }); } };