diff options
Diffstat (limited to 'app/assets/javascripts/boards/components')
15 files changed, 605 insertions, 593 deletions
diff --git a/app/assets/javascripts/boards/components/board.js b/app/assets/javascripts/boards/components/board.js index 623cda5679a..fb6e5291a61 100644 --- a/app/assets/javascripts/boards/components/board.js +++ b/app/assets/javascripts/boards/components/board.js @@ -42,7 +42,7 @@ export default Vue.extend({ required: true, }, }, - data () { + data() { return { detailIssue: boardsStore.detail, filter: boardsStore.filter, @@ -55,27 +55,26 @@ export default Vue.extend({ }, isNewIssueShown() { return this.list.type === 'backlog' || (!this.disabled && this.list.type !== 'closed'); - } + }, }, watch: { filter: { handler() { this.list.page = 1; - this.list.getIssues(true) - .catch(() => { - // TODO: handle request error - }); + this.list.getIssues(true).catch(() => { + // TODO: handle request error + }); }, deep: true, - } + }, }, - mounted () { + mounted() { this.sortableOptions = getBoardSortableDefaultOptions({ disabled: this.disabled, group: 'boards', draggable: '.is-draggable', handle: '.js-board-handle', - onEnd: (e) => { + onEnd: e => { sortableEnd(); if (e.newIndex !== undefined && e.oldIndex !== e.newIndex) { @@ -86,14 +85,15 @@ export default Vue.extend({ boardsStore.moveList(list, order); }); } - } + }, }); this.sortable = Sortable.create(this.$el.parentNode, this.sortableOptions); }, created() { if (this.list.isExpandable && AccessorUtilities.isLocalStorageAccessSafe()) { - const isCollapsed = localStorage.getItem(`boards.${this.boardId}.${this.list.type}.expanded`) === 'false'; + const isCollapsed = + localStorage.getItem(`boards.${this.boardId}.${this.list.type}.expanded`) === 'false'; this.list.isExpanded = !isCollapsed; } @@ -107,7 +107,10 @@ export default Vue.extend({ this.list.isExpanded = !this.list.isExpanded; if (AccessorUtilities.isLocalStorageAccessSafe()) { - localStorage.setItem(`boards.${this.boardId}.${this.list.type}.expanded`, this.list.isExpanded); + localStorage.setItem( + `boards.${this.boardId}.${this.list.type}.expanded`, + this.list.isExpanded, + ); } } }, diff --git a/app/assets/javascripts/boards/components/board_blank_state.vue b/app/assets/javascripts/boards/components/board_blank_state.vue index 38aaec73d7d..561a4636ef5 100644 --- a/app/assets/javascripts/boards/components/board_blank_state.vue +++ b/app/assets/javascripts/boards/components/board_blank_state.vue @@ -32,18 +32,18 @@ export default { boardsStore.state.lists = _.sortBy(boardsStore.state.lists, 'position'); // Save the labels - gl.boardService.generateDefaultLists() + gl.boardService + .generateDefaultLists() .then(res => res.data) - .then((data) => { - data.forEach((listObj) => { + .then(data => { + data.forEach(listObj => { const list = boardsStore.findList('title', listObj.title); list.id = listObj.id; list.label.id = listObj.label.id; - list.getIssues() - .catch(() => { - // TODO: handle request error - }); + list.getIssues().catch(() => { + // TODO: handle request error + }); }); }) .catch(() => { @@ -57,7 +57,6 @@ export default { clearBlankState: boardsStore.removeBlankState.bind(boardsStore), }, }; - </script> <template> diff --git a/app/assets/javascripts/boards/components/board_card.vue b/app/assets/javascripts/boards/components/board_card.vue index 843498f0d06..2f31316aa76 100644 --- a/app/assets/javascripts/boards/components/board_card.vue +++ b/app/assets/javascripts/boards/components/board_card.vue @@ -1,77 +1,77 @@ <script> - /* eslint-disable vue/require-default-prop */ - import IssueCardInner from './issue_card_inner.vue'; - import eventHub from '../eventhub'; - import boardsStore from '../stores/boards_store'; +/* eslint-disable vue/require-default-prop */ +import IssueCardInner from './issue_card_inner.vue'; +import eventHub from '../eventhub'; +import boardsStore from '../stores/boards_store'; - export default { - name: 'BoardsIssueCard', - components: { - IssueCardInner, +export default { + name: 'BoardsIssueCard', + components: { + IssueCardInner, + }, + props: { + list: { + type: Object, + default: () => ({}), }, - props: { - list: { - type: Object, - default: () => ({}), - }, - issue: { - type: Object, - default: () => ({}), - }, - issueLinkBase: { - type: String, - default: '', - }, - disabled: { - type: Boolean, - default: false, - }, - index: { - type: Number, - default: 0, - }, - rootPath: { - type: String, - default: '', - }, - groupId: { - type: Number, - }, + issue: { + type: Object, + default: () => ({}), }, - data() { - return { - showDetail: false, - detailIssue: boardsStore.detail, - }; + issueLinkBase: { + type: String, + default: '', }, - computed: { - issueDetailVisible() { - return this.detailIssue.issue && this.detailIssue.issue.id === this.issue.id; - }, + disabled: { + type: Boolean, + default: false, }, - methods: { - mouseDown() { - this.showDetail = true; - }, - mouseMove() { - this.showDetail = false; - }, - showIssue(e) { - if (e.target.classList.contains('js-no-trigger')) return; + index: { + type: Number, + default: 0, + }, + rootPath: { + type: String, + default: '', + }, + groupId: { + type: Number, + }, + }, + data() { + return { + showDetail: false, + detailIssue: boardsStore.detail, + }; + }, + computed: { + issueDetailVisible() { + return this.detailIssue.issue && this.detailIssue.issue.id === this.issue.id; + }, + }, + methods: { + mouseDown() { + this.showDetail = true; + }, + mouseMove() { + this.showDetail = false; + }, + showIssue(e) { + if (e.target.classList.contains('js-no-trigger')) return; - if (this.showDetail) { - this.showDetail = false; + if (this.showDetail) { + this.showDetail = false; - if (boardsStore.detail.issue && boardsStore.detail.issue.id === this.issue.id) { - eventHub.$emit('clearDetailIssue'); - } else { - eventHub.$emit('newDetailIssue', this.issue); - boardsStore.detail.list = this.list; - } + if (boardsStore.detail.issue && boardsStore.detail.issue.id === this.issue.id) { + eventHub.$emit('clearDetailIssue'); + } else { + eventHub.$emit('newDetailIssue', this.issue); + boardsStore.detail.list = this.list; } - }, + } }, - }; + }, +}; </script> <template> diff --git a/app/assets/javascripts/boards/components/board_new_issue.vue b/app/assets/javascripts/boards/components/board_new_issue.vue index ae2d1ee3c6e..ee3dc38bca6 100644 --- a/app/assets/javascripts/boards/components/board_new_issue.vue +++ b/app/assets/javascripts/boards/components/board_new_issue.vue @@ -62,7 +62,8 @@ export default { eventHub.$emit(`scroll-board-list-${this.list.id}`); this.cancel(); - return this.list.newIssue(issue) + return this.list + .newIssue(issue) .then(() => { // Need this because our jQuery very kindly disables buttons on ALL form submissions $(this.$refs.submitButton).enable(); diff --git a/app/assets/javascripts/boards/components/board_sidebar.js b/app/assets/javascripts/boards/components/board_sidebar.js index 62666954de0..e637e1f1223 100644 --- a/app/assets/javascripts/boards/components/board_sidebar.js +++ b/app/assets/javascripts/boards/components/board_sidebar.js @@ -38,7 +38,7 @@ export default Vue.extend({ }; }, computed: { - showSidebar () { + showSidebar() { return Object.keys(this.issue).length; }, milestoneTitle() { @@ -51,18 +51,20 @@ export default Vue.extend({ return this.issue.labels && this.issue.labels.length; }, labelDropdownTitle() { - return this.hasLabels ? sprintf(__('%{firstLabel} +%{labelCount} more'), { - firstLabel: this.issue.labels[0].title, - labelCount: this.issue.labels.length - 1 - }) : __('Label'); + return this.hasLabels + ? sprintf(__('%{firstLabel} +%{labelCount} more'), { + firstLabel: this.issue.labels[0].title, + labelCount: this.issue.labels.length - 1, + }) + : __('Label'); }, selectedLabels() { return this.hasLabels ? this.issue.labels.map(l => l.title).join(',') : ''; - } + }, }, watch: { detail: { - handler () { + handler() { if (this.issue.id !== this.detail.issue.id) { $('.block.assignee') .find('input:not(.js-vue)[name="issue[assignee_ids][]"]') @@ -71,17 +73,19 @@ export default Vue.extend({ }); $('.js-issue-board-sidebar', this.$el).each((i, el) => { - $(el).data('glDropdown').clearMenu(); + $(el) + .data('glDropdown') + .clearMenu(); }); } this.issue = this.detail.issue; this.list = this.detail.list; }, - deep: true + deep: true, }, }, - created () { + created() { // Get events from glDropdown eventHub.$on('sidebar.removeAssignee', this.removeAssignee); eventHub.$on('sidebar.addAssignee', this.addAssignee); @@ -94,7 +98,7 @@ export default Vue.extend({ eventHub.$off('sidebar.removeAllAssignees', this.removeAllAssignees); eventHub.$off('sidebar.saveAssignees', this.saveAssignees); }, - mounted () { + mounted() { new IssuableContext(this.currentUser); new MilestoneSelect(); new DueDateSelectors(); @@ -102,29 +106,30 @@ export default Vue.extend({ new Sidebar(); }, methods: { - closeSidebar () { + closeSidebar() { this.detail.issue = {}; }, - assignSelf () { + assignSelf() { // Notify gl dropdown that we are now assigning to current user this.$refs.assigneeBlock.dispatchEvent(new Event('assignYourself')); this.addAssignee(this.currentUser); this.saveAssignees(); }, - removeAssignee (a) { + removeAssignee(a) { boardsStore.detail.issue.removeAssignee(a); }, - addAssignee (a) { + addAssignee(a) { boardsStore.detail.issue.addAssignee(a); }, - removeAllAssignees () { + removeAllAssignees() { boardsStore.detail.issue.removeAllAssignees(); }, - saveAssignees () { + saveAssignees() { this.loadingAssignees = true; - boardsStore.detail.issue.update() + boardsStore.detail.issue + .update() .then(() => { this.loadingAssignees = false; }) diff --git a/app/assets/javascripts/boards/components/issue_card_inner.vue b/app/assets/javascripts/boards/components/issue_card_inner.vue index aa98f35786e..d956777a86b 100644 --- a/app/assets/javascripts/boards/components/issue_card_inner.vue +++ b/app/assets/javascripts/boards/components/issue_card_inner.vue @@ -1,142 +1,142 @@ <script> - import $ from 'jquery'; - import Icon from '~/vue_shared/components/icon.vue'; - import UserAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue'; - import eventHub from '../eventhub'; - import tooltip from '../../vue_shared/directives/tooltip'; - import boardsStore from '../stores/boards_store'; +import $ from 'jquery'; +import Icon from '~/vue_shared/components/icon.vue'; +import UserAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue'; +import eventHub from '../eventhub'; +import tooltip from '../../vue_shared/directives/tooltip'; +import boardsStore from '../stores/boards_store'; - export default { - components: { - UserAvatarLink, - Icon, - }, - directives: { - tooltip, - }, - props: { - issue: { - type: Object, - required: true, - }, - issueLinkBase: { - type: String, - required: true, - }, - list: { - type: Object, - required: false, - default: () => ({}), - }, - rootPath: { - type: String, - required: true, - }, - updateFilters: { - type: Boolean, - required: false, - default: false, - }, - groupId: { - type: Number, - required: false, - default: null, - }, - }, - data() { - return { - limitBeforeCounter: 3, - maxRender: 4, - maxCounter: 99, - }; +export default { + components: { + UserAvatarLink, + Icon, + }, + directives: { + tooltip, + }, + props: { + issue: { + type: Object, + required: true, }, - computed: { - numberOverLimit() { - return this.issue.assignees.length - this.limitBeforeCounter; - }, - assigneeCounterTooltip() { - return `${this.assigneeCounterLabel} more`; - }, - assigneeCounterLabel() { - if (this.numberOverLimit > this.maxCounter) { - return `${this.maxCounter}+`; - } - - return `+${this.numberOverLimit}`; - }, - shouldRenderCounter() { - if (this.issue.assignees.length <= this.maxRender) { - return false; - } + issueLinkBase: { + type: String, + required: true, + }, + list: { + type: Object, + required: false, + default: () => ({}), + }, + rootPath: { + type: String, + required: true, + }, + updateFilters: { + type: Boolean, + required: false, + default: false, + }, + groupId: { + type: Number, + required: false, + default: null, + }, + }, + data() { + return { + limitBeforeCounter: 3, + maxRender: 4, + maxCounter: 99, + }; + }, + computed: { + numberOverLimit() { + return this.issue.assignees.length - this.limitBeforeCounter; + }, + assigneeCounterTooltip() { + return `${this.assigneeCounterLabel} more`; + }, + assigneeCounterLabel() { + if (this.numberOverLimit > this.maxCounter) { + return `${this.maxCounter}+`; + } - return this.issue.assignees.length > this.numberOverLimit; - }, - issueId() { - if (this.issue.iid) { - return `#${this.issue.iid}`; - } + return `+${this.numberOverLimit}`; + }, + shouldRenderCounter() { + if (this.issue.assignees.length <= this.maxRender) { return false; - }, - showLabelFooter() { - return this.issue.labels.find(l => this.showLabel(l)) !== undefined; - }, - }, - methods: { - isIndexLessThanlimit(index) { - return index < this.limitBeforeCounter; - }, - shouldRenderAssignee(index) { - // Eg. maxRender is 4, - // Render up to all 4 assignees if there are only 4 assigness - // Otherwise render up to the limitBeforeCounter - if (this.issue.assignees.length <= this.maxRender) { - return index < this.maxRender; - } + } - return index < this.limitBeforeCounter; - }, - assigneeUrl(assignee) { - return `${this.rootPath}${assignee.username}`; - }, - assigneeUrlTitle(assignee) { - return `Assigned to ${assignee.name}`; - }, - avatarUrlTitle(assignee) { - return `Avatar for ${assignee.name}`; - }, - showLabel(label) { - if (!label.id) return false; - return true; - }, - filterByLabel(label, e) { - if (!this.updateFilters) return; + return this.issue.assignees.length > this.numberOverLimit; + }, + issueId() { + if (this.issue.iid) { + return `#${this.issue.iid}`; + } + return false; + }, + showLabelFooter() { + return this.issue.labels.find(l => this.showLabel(l)) !== undefined; + }, + }, + methods: { + isIndexLessThanlimit(index) { + return index < this.limitBeforeCounter; + }, + shouldRenderAssignee(index) { + // Eg. maxRender is 4, + // Render up to all 4 assignees if there are only 4 assigness + // Otherwise render up to the limitBeforeCounter + if (this.issue.assignees.length <= this.maxRender) { + return index < this.maxRender; + } + + return index < this.limitBeforeCounter; + }, + assigneeUrl(assignee) { + return `${this.rootPath}${assignee.username}`; + }, + assigneeUrlTitle(assignee) { + return `Assigned to ${assignee.name}`; + }, + avatarUrlTitle(assignee) { + return `Avatar for ${assignee.name}`; + }, + showLabel(label) { + if (!label.id) return false; + return true; + }, + filterByLabel(label, e) { + if (!this.updateFilters) return; - const filterPath = boardsStore.filter.path.split('&'); - const labelTitle = encodeURIComponent(label.title); - const param = `label_name[]=${labelTitle}`; - const labelIndex = filterPath.indexOf(param); - $(e.currentTarget).tooltip('hide'); + const filterPath = boardsStore.filter.path.split('&'); + const labelTitle = encodeURIComponent(label.title); + const param = `label_name[]=${labelTitle}`; + const labelIndex = filterPath.indexOf(param); + $(e.currentTarget).tooltip('hide'); - if (labelIndex === -1) { - filterPath.push(param); - } else { - filterPath.splice(labelIndex, 1); - } + if (labelIndex === -1) { + filterPath.push(param); + } else { + filterPath.splice(labelIndex, 1); + } - boardsStore.filter.path = filterPath.join('&'); + boardsStore.filter.path = filterPath.join('&'); - boardsStore.updateFiltersUrl(); + boardsStore.updateFiltersUrl(); - eventHub.$emit('updateTokens'); - }, - labelStyle(label) { - return { - backgroundColor: label.color, - color: label.textColor, - }; - }, - }, - }; + eventHub.$emit('updateTokens'); + }, + labelStyle(label) { + return { + backgroundColor: label.color, + color: label.textColor, + }; + }, + }, +}; </script> <template> <div> diff --git a/app/assets/javascripts/boards/components/modal/empty_state.vue b/app/assets/javascripts/boards/components/modal/empty_state.vue index dbd69f84526..795ba864545 100644 --- a/app/assets/javascripts/boards/components/modal/empty_state.vue +++ b/app/assets/javascripts/boards/components/modal/empty_state.vue @@ -20,7 +20,7 @@ export default { computed: { contents() { const obj = { - title: 'You haven\'t added any issues to your project yet', + title: "You haven't added any issues to your project yet", content: ` An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable. @@ -28,7 +28,7 @@ export default { }; if (this.activeTab === 'selected') { - obj.title = 'You haven\'t selected any issues yet'; + obj.title = "You haven't selected any issues yet"; obj.content = ` Go back to <strong>Open issues</strong> and select some issues to add to your board. diff --git a/app/assets/javascripts/boards/components/modal/footer.vue b/app/assets/javascripts/boards/components/modal/footer.vue index 268ca6bca13..d51597ed22d 100644 --- a/app/assets/javascripts/boards/components/modal/footer.vue +++ b/app/assets/javascripts/boards/components/modal/footer.vue @@ -42,19 +42,17 @@ export default { const req = this.buildUpdateRequest(list); // Post the data to the backend - gl.boardService - .bulkUpdate(issueIds, req) - .catch(() => { - Flash(__('Failed to update issues, please try again.')); + gl.boardService.bulkUpdate(issueIds, req).catch(() => { + Flash(__('Failed to update issues, please try again.')); - selectedIssues.forEach((issue) => { - list.removeIssue(issue); - list.issuesSize -= 1; - }); + selectedIssues.forEach(issue => { + list.removeIssue(issue); + list.issuesSize -= 1; }); + }); // Add the issues on the frontend - selectedIssues.forEach((issue) => { + selectedIssues.forEach(issue => { list.addIssue(issue); list.issuesSize += 1; }); diff --git a/app/assets/javascripts/boards/components/modal/header.vue b/app/assets/javascripts/boards/components/modal/header.vue index 979fb4d7199..fc6cefa89a9 100644 --- a/app/assets/javascripts/boards/components/modal/header.vue +++ b/app/assets/javascripts/boards/components/modal/header.vue @@ -1,52 +1,52 @@ <script> - import ModalFilters from './filters'; - import ModalTabs from './tabs.vue'; - import ModalStore from '../../stores/modal_store'; - import modalMixin from '../../mixins/modal_mixins'; +import ModalFilters from './filters'; +import ModalTabs from './tabs.vue'; +import ModalStore from '../../stores/modal_store'; +import modalMixin from '../../mixins/modal_mixins'; - export default { - components: { - ModalTabs, - ModalFilters, +export default { + components: { + ModalTabs, + ModalFilters, + }, + mixins: [modalMixin], + props: { + projectId: { + type: Number, + required: true, }, - mixins: [modalMixin], - props: { - projectId: { - type: Number, - required: true, - }, - milestonePath: { - type: String, - required: true, - }, - labelPath: { - type: String, - required: true, - }, + milestonePath: { + type: String, + required: true, }, - data() { - return ModalStore.store; + labelPath: { + type: String, + required: true, }, - computed: { - selectAllText() { - if (ModalStore.selectedCount() !== this.issues.length || this.issues.length === 0) { - return 'Select all'; - } + }, + data() { + return ModalStore.store; + }, + computed: { + selectAllText() { + if (ModalStore.selectedCount() !== this.issues.length || this.issues.length === 0) { + return 'Select all'; + } - return 'Deselect all'; - }, - showSearch() { - return this.activeTab === 'all' && !this.loading && this.issuesCount > 0; - }, + return 'Deselect all'; }, - methods: { - toggleAll() { - this.$refs.selectAllBtn.blur(); + showSearch() { + return this.activeTab === 'all' && !this.loading && this.issuesCount > 0; + }, + }, + methods: { + toggleAll() { + this.$refs.selectAllBtn.blur(); - ModalStore.toggleAll(); - }, + ModalStore.toggleAll(); }, - }; + }, +}; </script> <template> <div> diff --git a/app/assets/javascripts/boards/components/modal/index.vue b/app/assets/javascripts/boards/components/modal/index.vue index 0c4c709324d..40949cc0656 100644 --- a/app/assets/javascripts/boards/components/modal/index.vue +++ b/app/assets/javascripts/boards/components/modal/index.vue @@ -1,143 +1,144 @@ <script> - /* global ListIssue */ - import { urlParamsToObject } from '~/lib/utils/common_utils'; - import ModalHeader from './header.vue'; - import ModalList from './list.vue'; - import ModalFooter from './footer.vue'; - import EmptyState from './empty_state.vue'; - import ModalStore from '../../stores/modal_store'; +/* global ListIssue */ +import { urlParamsToObject } from '~/lib/utils/common_utils'; +import ModalHeader from './header.vue'; +import ModalList from './list.vue'; +import ModalFooter from './footer.vue'; +import EmptyState from './empty_state.vue'; +import ModalStore from '../../stores/modal_store'; - export default { - components: { - EmptyState, - ModalHeader, - ModalList, - ModalFooter, +export default { + components: { + EmptyState, + ModalHeader, + ModalList, + ModalFooter, + }, + props: { + newIssuePath: { + type: String, + required: true, }, - props: { - newIssuePath: { - type: String, - required: true, - }, - emptyStateSvg: { - type: String, - required: true, - }, - issueLinkBase: { - type: String, - required: true, - }, - rootPath: { - type: String, - required: true, - }, - projectId: { - type: Number, - required: true, - }, - milestonePath: { - type: String, - required: true, - }, - labelPath: { - type: String, - required: true, - }, + emptyStateSvg: { + type: String, + required: true, }, - data() { - return ModalStore.store; + issueLinkBase: { + type: String, + required: true, }, - computed: { - showList() { - if (this.activeTab === 'selected') { - return this.selectedIssues.length > 0; - } + rootPath: { + type: String, + required: true, + }, + projectId: { + type: Number, + required: true, + }, + milestonePath: { + type: String, + required: true, + }, + labelPath: { + type: String, + required: true, + }, + }, + data() { + return ModalStore.store; + }, + computed: { + showList() { + if (this.activeTab === 'selected') { + return this.selectedIssues.length > 0; + } - return this.issuesCount > 0; - }, - showEmptyState() { - if (!this.loading && this.issuesCount === 0) { - return true; - } + return this.issuesCount > 0; + }, + showEmptyState() { + if (!this.loading && this.issuesCount === 0) { + return true; + } - return this.activeTab === 'selected' && this.selectedIssues.length === 0; - }, + return this.activeTab === 'selected' && this.selectedIssues.length === 0; }, - watch: { - page() { - this.loadIssues(); - }, - showAddIssuesModal() { - if (this.showAddIssuesModal && !this.issues.length) { - this.loading = true; + }, + watch: { + page() { + this.loadIssues(); + }, + showAddIssuesModal() { + if (this.showAddIssuesModal && !this.issues.length) { + this.loading = true; + const loadingDone = () => { + this.loading = false; + }; + + this.loadIssues() + .then(loadingDone) + .catch(loadingDone); + } else if (!this.showAddIssuesModal) { + this.issues = []; + this.selectedIssues = []; + this.issuesCount = false; + } + }, + filter: { + handler() { + if (this.$el.tagName) { + this.page = 1; + this.filterLoading = true; const loadingDone = () => { - this.loading = false; + this.filterLoading = false; }; - this.loadIssues() + this.loadIssues(true) .then(loadingDone) .catch(loadingDone); - } else if (!this.showAddIssuesModal) { - this.issues = []; - this.selectedIssues = []; - this.issuesCount = false; } }, - filter: { - handler() { - if (this.$el.tagName) { - this.page = 1; - this.filterLoading = true; - const loadingDone = () => { - this.filterLoading = false; - }; - - this.loadIssues(true) - .then(loadingDone) - .catch(loadingDone); - } - }, - deep: true, - }, + deep: true, }, - created() { - this.page = 1; - }, - methods: { - loadIssues(clearIssues = false) { - if (!this.showAddIssuesModal) return false; + }, + created() { + this.page = 1; + }, + methods: { + loadIssues(clearIssues = false) { + if (!this.showAddIssuesModal) return false; - return gl.boardService.getBacklog({ + return gl.boardService + .getBacklog({ ...urlParamsToObject(this.filter.path), page: this.page, per: this.perPage, }) - .then(res => res.data) - .then(data => { - if (clearIssues) { - this.issues = []; - } + .then(res => res.data) + .then(data => { + if (clearIssues) { + this.issues = []; + } - data.issues.forEach(issueObj => { - const issue = new ListIssue(issueObj); - const foundSelectedIssue = ModalStore.findSelectedIssue(issue); - issue.selected = !!foundSelectedIssue; + data.issues.forEach(issueObj => { + const issue = new ListIssue(issueObj); + const foundSelectedIssue = ModalStore.findSelectedIssue(issue); + issue.selected = !!foundSelectedIssue; - this.issues.push(issue); - }); + this.issues.push(issue); + }); - this.loadingNewPage = false; + this.loadingNewPage = false; - if (!this.issuesCount) { - this.issuesCount = data.size; - } - }) - .catch(() => { - // TODO: handle request error - }); - }, + if (!this.issuesCount) { + this.issuesCount = data.size; + } + }) + .catch(() => { + // TODO: handle request error + }); }, - }; + }, +}; </script> <template> <div diff --git a/app/assets/javascripts/boards/components/modal/list.vue b/app/assets/javascripts/boards/components/modal/list.vue index c93fd9f415c..e11f398e70d 100644 --- a/app/assets/javascripts/boards/components/modal/list.vue +++ b/app/assets/javascripts/boards/components/modal/list.vue @@ -1,120 +1,120 @@ <script> - import Icon from '~/vue_shared/components/icon.vue'; - import bp from '../../../breakpoints'; - import ModalStore from '../../stores/modal_store'; - import IssueCardInner from '../issue_card_inner.vue'; +import Icon from '~/vue_shared/components/icon.vue'; +import bp from '../../../breakpoints'; +import ModalStore from '../../stores/modal_store'; +import IssueCardInner from '../issue_card_inner.vue'; - export default { - components: { - IssueCardInner, - Icon, +export default { + components: { + IssueCardInner, + Icon, + }, + props: { + issueLinkBase: { + type: String, + required: true, }, - props: { - issueLinkBase: { - type: String, - required: true, - }, - rootPath: { - type: String, - required: true, - }, - emptyStateSvg: { - type: String, - required: true, - }, + rootPath: { + type: String, + required: true, }, - data() { - return ModalStore.store; + emptyStateSvg: { + type: String, + required: true, }, - computed: { - loopIssues() { - if (this.activeTab === 'all') { - return this.issues; - } + }, + data() { + return ModalStore.store; + }, + computed: { + loopIssues() { + if (this.activeTab === 'all') { + return this.issues; + } - return this.selectedIssues; - }, - groupedIssues() { - const groups = []; - this.loopIssues.forEach((issue, i) => { - const index = i % this.columns; + return this.selectedIssues; + }, + groupedIssues() { + const groups = []; + this.loopIssues.forEach((issue, i) => { + const index = i % this.columns; - if (!groups[index]) { - groups.push([]); - } + if (!groups[index]) { + groups.push([]); + } - groups[index].push(issue); - }); + groups[index].push(issue); + }); - return groups; - }, + return groups; }, - watch: { - activeTab() { - if (this.activeTab === 'all') { - ModalStore.purgeUnselectedIssues(); - } - }, + }, + watch: { + activeTab() { + if (this.activeTab === 'all') { + ModalStore.purgeUnselectedIssues(); + } }, - mounted() { - this.scrollHandlerWrapper = this.scrollHandler.bind(this); - this.setColumnCountWrapper = this.setColumnCount.bind(this); - this.setColumnCount(); + }, + mounted() { + this.scrollHandlerWrapper = this.scrollHandler.bind(this); + this.setColumnCountWrapper = this.setColumnCount.bind(this); + this.setColumnCount(); - this.$refs.list.addEventListener('scroll', this.scrollHandlerWrapper); - window.addEventListener('resize', this.setColumnCountWrapper); + this.$refs.list.addEventListener('scroll', this.scrollHandlerWrapper); + window.addEventListener('resize', this.setColumnCountWrapper); + }, + beforeDestroy() { + this.$refs.list.removeEventListener('scroll', this.scrollHandlerWrapper); + window.removeEventListener('resize', this.setColumnCountWrapper); + }, + methods: { + scrollHandler() { + const currentPage = Math.floor(this.issues.length / this.perPage); + + if ( + this.scrollTop() > this.scrollHeight() - 100 && + !this.loadingNewPage && + currentPage === this.page + ) { + this.loadingNewPage = true; + this.page += 1; + } }, - beforeDestroy() { - this.$refs.list.removeEventListener('scroll', this.scrollHandlerWrapper); - window.removeEventListener('resize', this.setColumnCountWrapper); + toggleIssue(e, issue) { + if (e.target.tagName !== 'A') { + ModalStore.toggleIssue(issue); + } }, - methods: { - scrollHandler() { - const currentPage = Math.floor(this.issues.length / this.perPage); - - if ( - this.scrollTop() > this.scrollHeight() - 100 && - !this.loadingNewPage && - currentPage === this.page - ) { - this.loadingNewPage = true; - this.page += 1; - } - }, - toggleIssue(e, issue) { - if (e.target.tagName !== 'A') { - ModalStore.toggleIssue(issue); - } - }, - listHeight() { - return this.$refs.list.getBoundingClientRect().height; - }, - scrollHeight() { - return this.$refs.list.scrollHeight; - }, - scrollTop() { - return this.$refs.list.scrollTop + this.listHeight(); - }, - showIssue(issue) { - if (this.activeTab === 'all') return true; + listHeight() { + return this.$refs.list.getBoundingClientRect().height; + }, + scrollHeight() { + return this.$refs.list.scrollHeight; + }, + scrollTop() { + return this.$refs.list.scrollTop + this.listHeight(); + }, + showIssue(issue) { + if (this.activeTab === 'all') return true; - const index = ModalStore.selectedIssueIndex(issue); + const index = ModalStore.selectedIssueIndex(issue); - return index !== -1; - }, - setColumnCount() { - const breakpoint = bp.getBreakpointSize(); + return index !== -1; + }, + setColumnCount() { + const breakpoint = bp.getBreakpointSize(); - if (breakpoint === 'lg' || breakpoint === 'md') { - this.columns = 3; - } else if (breakpoint === 'sm') { - this.columns = 2; - } else { - this.columns = 1; - } - }, + if (breakpoint === 'lg' || breakpoint === 'md') { + this.columns = 3; + } else if (breakpoint === 'sm') { + this.columns = 2; + } else { + this.columns = 1; + } }, - }; + }, +}; </script> <template> <section diff --git a/app/assets/javascripts/boards/components/modal/tabs.vue b/app/assets/javascripts/boards/components/modal/tabs.vue index d926b080094..5d661590e8e 100644 --- a/app/assets/javascripts/boards/components/modal/tabs.vue +++ b/app/assets/javascripts/boards/components/modal/tabs.vue @@ -1,21 +1,21 @@ <script> - import ModalStore from '../../stores/modal_store'; - import modalMixin from '../../mixins/modal_mixins'; +import ModalStore from '../../stores/modal_store'; +import modalMixin from '../../mixins/modal_mixins'; - export default { - mixins: [modalMixin], - data() { - return ModalStore.store; +export default { + mixins: [modalMixin], + data() { + return ModalStore.store; + }, + computed: { + selectedCount() { + return ModalStore.selectedCount(); }, - computed: { - selectedCount() { - return ModalStore.selectedCount(); - }, - }, - destroyed() { - this.activeTab = 'all'; - }, - }; + }, + destroyed() { + this.activeTab = 'all'; + }, +}; </script> <template> <div class="top-area prepend-top-10 append-bottom-10"> diff --git a/app/assets/javascripts/boards/components/new_list_dropdown.js b/app/assets/javascripts/boards/components/new_list_dropdown.js index 2c2045f8901..f7016561f93 100644 --- a/app/assets/javascripts/boards/components/new_list_dropdown.js +++ b/app/assets/javascripts/boards/components/new_list_dropdown.js @@ -6,36 +6,41 @@ import _ from 'underscore'; import CreateLabelDropdown from '../../create_label'; import boardsStore from '../stores/boards_store'; -$(document).off('created.label').on('created.label', (e, label) => { - boardsStore.new({ - title: label.title, - position: boardsStore.state.lists.length - 2, - list_type: 'label', - label: { - id: label.id, +$(document) + .off('created.label') + .on('created.label', (e, label) => { + boardsStore.new({ title: label.title, - color: label.color, - }, + position: boardsStore.state.lists.length - 2, + list_type: 'label', + label: { + id: label.id, + title: label.title, + color: label.color, + }, + }); }); -}); export default function initNewListDropdown() { - $('.js-new-board-list').each(function () { + $('.js-new-board-list').each(function() { const $this = $(this); - new CreateLabelDropdown($this.closest('.dropdown').find('.dropdown-new-label'), $this.data('namespacePath'), $this.data('projectPath')); + new CreateLabelDropdown( + $this.closest('.dropdown').find('.dropdown-new-label'), + $this.data('namespacePath'), + $this.data('projectPath'), + ); $this.glDropdown({ data(term, callback) { - axios.get($this.attr('data-list-labels-path')) - .then(({ data }) => { - callback(data); - }); + axios.get($this.attr('data-list-labels-path')).then(({ data }) => { + callback(data); + }); }, - renderRow (label) { + renderRow(label) { const active = boardsStore.findList('title', label.title); const $li = $('<li />'); const $a = $('<a />', { - class: (active ? `is-active js-board-list-${active.id}` : ''), + class: active ? `is-active js-board-list-${active.id}` : '', text: label.title, href: '#', }); @@ -53,7 +58,7 @@ export default function initNewListDropdown() { selectable: true, multiSelect: true, containerSelector: '.js-tab-container-labels .dropdown-page-one .dropdown-content', - clicked (options) { + clicked(options) { const { e } = options; const label = options.selectedObj; e.preventDefault(); diff --git a/app/assets/javascripts/boards/components/project_select.vue b/app/assets/javascripts/boards/components/project_select.vue index 427a0868b0c..0f01a2a6c09 100644 --- a/app/assets/javascripts/boards/components/project_select.vue +++ b/app/assets/javascripts/boards/components/project_select.vue @@ -46,7 +46,7 @@ export default { selectable: true, data: (term, callback) => { this.loading = true; - return Api.groupProjects(this.groupId, term, {with_issues_enabled: true}, projects => { + return Api.groupProjects(this.groupId, term, { with_issues_enabled: true }, projects => { this.loading = false; callback(projects); }); @@ -54,7 +54,9 @@ export default { renderRow(project) { return ` <li> - <a href='#' class='dropdown-menu-link' data-project-id="${project.id}" data-project-name="${project.name}"> + <a href='#' class='dropdown-menu-link' data-project-id="${ + project.id + }" data-project-name="${project.name}"> ${_.escape(project.name)} </a> </li> diff --git a/app/assets/javascripts/boards/components/sidebar/remove_issue.vue b/app/assets/javascripts/boards/components/sidebar/remove_issue.vue index b8f2e324d43..d681e6a431c 100644 --- a/app/assets/javascripts/boards/components/sidebar/remove_issue.vue +++ b/app/assets/javascripts/boards/components/sidebar/remove_issue.vue @@ -1,79 +1,77 @@ <script> - import Vue from 'vue'; - import Flash from '../../../flash'; - import { __ } from '../../../locale'; - import boardsStore from '../../stores/boards_store'; +import Vue from 'vue'; +import Flash from '../../../flash'; +import { __ } from '../../../locale'; +import boardsStore from '../../stores/boards_store'; - export default Vue.extend({ - props: { - issue: { - type: Object, - required: true, - }, - list: { - type: Object, - required: true, - }, +export default Vue.extend({ + props: { + issue: { + type: Object, + required: true, }, - computed: { - updateUrl() { - return this.issue.path; - }, + list: { + type: Object, + required: true, }, - methods: { - removeIssue() { - const { issue } = this; - const lists = issue.getLists(); - const req = this.buildPatchRequest(issue, lists); - - const data = { - issue: this.seedPatchRequest(issue, req), - }; + }, + computed: { + updateUrl() { + return this.issue.path; + }, + }, + methods: { + removeIssue() { + const { issue } = this; + const lists = issue.getLists(); + const req = this.buildPatchRequest(issue, lists); - if (data.issue.label_ids.length === 0) { - data.issue.label_ids = ['']; - } + const data = { + issue: this.seedPatchRequest(issue, req), + }; - // Post the remove data - Vue.http.patch(this.updateUrl, data).catch(() => { - Flash(__('Failed to remove issue from board, please try again.')); + if (data.issue.label_ids.length === 0) { + data.issue.label_ids = ['']; + } - lists.forEach(list => { - list.addIssue(issue); - }); - }); + // Post the remove data + Vue.http.patch(this.updateUrl, data).catch(() => { + Flash(__('Failed to remove issue from board, please try again.')); - // Remove from the frontend store lists.forEach(list => { - list.removeIssue(issue); + list.addIssue(issue); }); + }); - boardsStore.detail.issue = {}; - }, - /** - * Build the default patch request. - */ - buildPatchRequest(issue, lists) { - const listLabelIds = lists.map(list => list.label.id); + // Remove from the frontend store + lists.forEach(list => { + list.removeIssue(issue); + }); - const labelIds = issue.labels - .map(label => label.id) - .filter(id => !listLabelIds.includes(id)); + boardsStore.detail.issue = {}; + }, + /** + * Build the default patch request. + */ + buildPatchRequest(issue, lists) { + const listLabelIds = lists.map(list => list.label.id); + + const labelIds = issue.labels.map(label => label.id).filter(id => !listLabelIds.includes(id)); - return { - label_ids: labelIds, - }; - }, - /** - * Seed the given patch request. - * - * (This is overridden in EE) - */ - seedPatchRequest(issue, req) { - return req; - }, + return { + label_ids: labelIds, + }; + }, + /** + * Seed the given patch request. + * + * (This is overridden in EE) + */ + seedPatchRequest(issue, req) { + return req; }, - }); + }, +}); </script> <template> <div |