diff options
85 files changed, 2283 insertions, 2089 deletions
diff --git a/app/assets/javascripts/blob_edit/blob_bundle.js b/app/assets/javascripts/blob_edit/blob_bundle.js index 3cc89ff1955..ec27ae8c291 100644 --- a/app/assets/javascripts/blob_edit/blob_bundle.js +++ b/app/assets/javascripts/blob_edit/blob_bundle.js @@ -13,7 +13,7 @@ export default () => { if (editBlobForm.length) { const urlRoot = editBlobForm.data('relativeUrlRoot'); const assetsPath = editBlobForm.data('assetsPrefix'); - const filePath = editBlobForm.data('blobFilename') + const filePath = editBlobForm.data('blobFilename'); const currentAction = $('.js-file-title').data('currentAction'); const projectId = editBlobForm.data('project-id'); 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 diff --git a/app/assets/javascripts/boards/filtered_search_boards.js b/app/assets/javascripts/boards/filtered_search_boards.js index acf41e5689e..c14d69c5d18 100644 --- a/app/assets/javascripts/boards/filtered_search_boards.js +++ b/app/assets/javascripts/boards/filtered_search_boards.js @@ -32,7 +32,7 @@ export default class FilteredSearchBoards extends FilteredSearchManager { const tokens = FilteredSearchContainer.container.querySelectorAll('.js-visual-token'); // Remove all the tokens as they will be replaced by the search manager - [].forEach.call(tokens, (el) => { + [].forEach.call(tokens, el => { el.parentNode.removeChild(el); }); @@ -50,7 +50,10 @@ export default class FilteredSearchBoards extends FilteredSearchManager { canEdit(tokenName, tokenValue) { if (this.cantEdit.includes(tokenName)) return false; - return this.cantEditWithValue.findIndex(token => token.name === tokenName && - token.value === tokenValue) === -1; + return ( + this.cantEditWithValue.findIndex( + token => token.name === tokenName && token.value === tokenValue, + ) === -1 + ); } } diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js index 91861f2f9ee..61a3072ac27 100644 --- a/app/assets/javascripts/boards/index.js +++ b/app/assets/javascripts/boards/index.js @@ -32,9 +32,9 @@ 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; + window.addEventListener('pageshow', event => { + const isNavTypeBackForward = + window.performance && window.performance.navigation.type === NavigationType.TYPE_BACK_FORWARD; if (event.persisted || isNavTypeBackForward) { window.location.reload(); diff --git a/app/assets/javascripts/boards/mixins/sortable_default_options.js b/app/assets/javascripts/boards/mixins/sortable_default_options.js index c9cde4effb9..983b28d2e67 100644 --- a/app/assets/javascripts/boards/mixins/sortable_default_options.js +++ b/app/assets/javascripts/boards/mixins/sortable_default_options.js @@ -4,7 +4,8 @@ import $ from 'jquery'; import sortableConfig from '../../sortable/sortable_config'; export function sortableStart() { - $('.has-tooltip').tooltip('hide') + $('.has-tooltip') + .tooltip('hide') .tooltip('disable'); document.body.classList.add('is-dragging'); } @@ -15,7 +16,8 @@ export function sortableEnd() { } export function getBoardSortableDefaultOptions(obj) { - const touchEnabled = ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch; + const touchEnabled = + 'ontouchstart' in window || (window.DocumentTouch && document instanceof DocumentTouch); const defaultSortOptions = Object.assign({}, sortableConfig, { filter: '.board-delete, .btn', @@ -26,6 +28,8 @@ export function getBoardSortableDefaultOptions(obj) { onEnd: sortableEnd, }); - Object.keys(obj).forEach((key) => { defaultSortOptions[key] = obj[key]; }); + Object.keys(obj).forEach(key => { + defaultSortOptions[key] = obj[key]; + }); return defaultSortOptions; } diff --git a/app/assets/javascripts/boards/models/issue.js b/app/assets/javascripts/boards/models/issue.js index 52d04389b88..bb3b2865934 100644 --- a/app/assets/javascripts/boards/models/issue.js +++ b/app/assets/javascripts/boards/models/issue.js @@ -9,7 +9,7 @@ import IssueProject from './project'; import boardsStore from '../stores/boards_store'; class ListIssue { - constructor (obj, defaultAvatar) { + constructor(obj, defaultAvatar) { this.id = obj.id; this.iid = obj.iid; this.title = obj.title; @@ -39,54 +39,54 @@ class ListIssue { this.milestone = new ListMilestone(obj.milestone); } - obj.labels.forEach((label) => { + obj.labels.forEach(label => { this.labels.push(new ListLabel(label)); }); this.assignees = obj.assignees.map(a => new ListAssignee(a, defaultAvatar)); } - addLabel (label) { + addLabel(label) { if (!this.findLabel(label)) { this.labels.push(new ListLabel(label)); } } - findLabel (findLabel) { + findLabel(findLabel) { return this.labels.filter(label => label.title === findLabel.title)[0]; } - removeLabel (removeLabel) { + removeLabel(removeLabel) { if (removeLabel) { this.labels = this.labels.filter(label => removeLabel.title !== label.title); } } - removeLabels (labels) { + removeLabels(labels) { labels.forEach(this.removeLabel.bind(this)); } - addAssignee (assignee) { + addAssignee(assignee) { if (!this.findAssignee(assignee)) { this.assignees.push(new ListAssignee(assignee)); } } - findAssignee (findAssignee) { + findAssignee(findAssignee) { return this.assignees.filter(assignee => assignee.id === findAssignee.id)[0]; } - removeAssignee (removeAssignee) { + removeAssignee(removeAssignee) { if (removeAssignee) { this.assignees = this.assignees.filter(assignee => assignee.id !== removeAssignee.id); } } - removeAllAssignees () { + removeAllAssignees() { this.assignees = []; } - getLists () { + getLists() { return boardsStore.state.lists.filter(list => list.findIssue(this.id)); } @@ -102,14 +102,14 @@ class ListIssue { this.isLoading[key] = value; } - update () { + update() { const data = { issue: { milestone_id: this.milestone ? this.milestone.id : null, due_date: this.dueDate, - assignee_ids: this.assignees.length > 0 ? this.assignees.map((u) => u.id) : [0], - label_ids: this.labels.map((label) => label.id) - } + assignee_ids: this.assignees.length > 0 ? this.assignees.map(u => u.id) : [0], + label_ids: this.labels.map(label => label.id), + }, }; if (!data.issue.label_ids.length) { diff --git a/app/assets/javascripts/boards/models/list.js b/app/assets/javascripts/boards/models/list.js index 3161f1da8c9..dd3feedbc0e 100644 --- a/app/assets/javascripts/boards/models/list.js +++ b/app/assets/javascripts/boards/models/list.js @@ -234,11 +234,11 @@ class List { }); } - getTypeInfo (type) { + getTypeInfo(type) { return TYPES[type] || {}; } - onNewIssueResponse (issue, data) { + onNewIssueResponse(issue, data) { issue.id = data.id; issue.iid = data.iid; issue.project = data.project; diff --git a/app/assets/javascripts/boards/services/board_service.js b/app/assets/javascripts/boards/services/board_service.js index 029b0971f2c..3de6eb056c2 100644 --- a/app/assets/javascripts/boards/services/board_service.js +++ b/app/assets/javascripts/boards/services/board_service.js @@ -19,7 +19,9 @@ export default class BoardService { } static generateIssuePath(boardId, id) { - return `${gon.relative_url_root}/-/boards/${boardId ? `${boardId}` : ''}/issues${id ? `/${id}` : ''}`; + return `${gon.relative_url_root}/-/boards/${boardId ? `${boardId}` : ''}/issues${ + id ? `/${id}` : '' + }`; } all() { @@ -54,7 +56,9 @@ export default class BoardService { getIssuesForList(id, filter = {}) { const data = { id }; - Object.keys(filter).forEach((key) => { data[key] = filter[key]; }); + Object.keys(filter).forEach(key => { + data[key] = filter[key]; + }); return axios.get(mergeUrlParams(data, this.generateIssuesPath(id))); } @@ -75,7 +79,9 @@ export default class BoardService { } getBacklog(data) { - return axios.get(mergeUrlParams(data, `${gon.relative_url_root}/-/boards/${this.boardId}/issues.json`)); + return axios.get( + mergeUrlParams(data, `${gon.relative_url_root}/-/boards/${this.boardId}/issues.json`), + ); } bulkUpdate(issueIds, extraData = {}) { diff --git a/app/assets/javascripts/boards/stores/boards_store.js b/app/assets/javascripts/boards/stores/boards_store.js index 471955747fd..eefe14a1d79 100644 --- a/app/assets/javascripts/boards/stores/boards_store.js +++ b/app/assets/javascripts/boards/stores/boards_store.js @@ -20,20 +20,20 @@ const boardsStore = { issue: {}, list: {}, }, - create () { + create() { this.state.lists = []; this.filter.path = getUrlParamsArray().join('&'); this.detail = { issue: {}, }; }, - addList (listObj, defaultAvatar) { + addList(listObj, defaultAvatar) { const list = new List(listObj, defaultAvatar); this.state.lists.push(list); return list; }, - new (listObj) { + new(listObj) { const list = this.addList(listObj); const backlogList = this.findList('type', 'backlog', 'backlog'); @@ -50,44 +50,44 @@ const boardsStore = { }); this.removeBlankState(); }, - updateNewListDropdown (listId) { + updateNewListDropdown(listId) { $(`.js-board-list-${listId}`).removeClass('is-active'); }, - shouldAddBlankState () { + shouldAddBlankState() { // Decide whether to add the blank state - return !(this.state.lists.filter(list => list.type !== 'backlog' && list.type !== 'closed')[0]); + return !this.state.lists.filter(list => list.type !== 'backlog' && list.type !== 'closed')[0]; }, - addBlankState () { + addBlankState() { if (!this.shouldAddBlankState() || this.welcomeIsHidden() || this.disabled) return; this.addList({ id: 'blank', list_type: 'blank', title: 'Welcome to your Issue Board!', - position: 0 + position: 0, }); this.state.lists = _.sortBy(this.state.lists, 'position'); }, - removeBlankState () { + removeBlankState() { this.removeList('blank'); Cookies.set('issue_board_welcome_hidden', 'true', { expires: 365 * 10, - path: '' + path: '', }); }, - welcomeIsHidden () { + welcomeIsHidden() { return Cookies.get('issue_board_welcome_hidden') === 'true'; }, - removeList (id, type = 'blank') { + 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) { + moveList(listFrom, orderLists) { orderLists.forEach((id, i) => { const list = this.findList('id', parseInt(id, 10)); @@ -95,22 +95,25 @@ const boardsStore = { }); listFrom.update(); }, - moveIssueToList (listFrom, listTo, issue, newIndex) { + moveIssueToList(listFrom, listTo, issue, newIndex) { const issueTo = listTo.findIssue(issue.id); const issueLists = issue.getLists(); const listLabels = issueLists.map(listIssue => listIssue.label); if (!issueTo) { // Check if target list assignee is already present in this issue - if ((listTo.type === 'assignee' && listFrom.type === 'assignee') && - issue.findAssignee(listTo.assignee)) { + if ( + listTo.type === 'assignee' && + listFrom.type === 'assignee' && + issue.findAssignee(listTo.assignee) + ) { const targetIssue = listTo.findIssue(issue.id); targetIssue.removeAssignee(listFrom.assignee); } else if (listTo.type === 'milestone') { const currentMilestone = issue.milestone; const currentLists = this.state.lists - .filter(list => (list.type === 'milestone' && list.id !== listTo.id)) - .filter(list => list.issues.some(listIssue => issue.id === listIssue.id)); + .filter(list => list.type === 'milestone' && list.id !== listTo.id) + .filter(list => list.issues.some(listIssue => issue.id === listIssue.id)); issue.removeMilestone(currentMilestone); issue.addMilestone(listTo.milestone); @@ -126,7 +129,7 @@ const boardsStore = { } if (listTo.type === 'closed' && listFrom.type !== 'backlog') { - issueLists.forEach((list) => { + issueLists.forEach(list => { list.removeIssue(issue); }); issue.removeLabels(listLabels); @@ -144,26 +147,28 @@ const boardsStore = { return ( (listTo.type !== 'label' && listFrom.type === 'assignee') || (listTo.type !== 'assignee' && listFrom.type === 'label') || - (listFrom.type === 'backlog') + listFrom.type === 'backlog' ); }, - moveIssueInList (list, issue, oldIndex, newIndex, idArray) { + moveIssueInList(list, issue, oldIndex, newIndex, idArray) { const beforeId = parseInt(idArray[newIndex - 1], 10) || null; const afterId = parseInt(idArray[newIndex + 1], 10) || null; list.moveIssue(issue, oldIndex, newIndex, beforeId, afterId); }, - findList (key, val, type = 'label') { - const filteredList = this.state.lists.filter((list) => { - const byType = type ? (list.type === type) || (list.type === 'assignee') || (list.type === 'milestone') : true; + findList(key, val, type = 'label') { + const filteredList = this.state.lists.filter(list => { + const byType = type + ? list.type === type || list.type === 'assignee' || list.type === 'milestone' + : true; return list[key] === val && byType; }); return filteredList[0]; }, - updateFiltersUrl () { + updateFiltersUrl() { window.history.pushState(null, null, `?${this.filter.path}`); - } + }, }; // hacks added in order to allow milestone_select to function properly diff --git a/app/assets/javascripts/boards/stores/modal_store.js b/app/assets/javascripts/boards/stores/modal_store.js index 0d9ac367a70..b7228bf7bf5 100644 --- a/app/assets/javascripts/boards/stores/modal_store.js +++ b/app/assets/javascripts/boards/stores/modal_store.js @@ -40,7 +40,7 @@ class ModalStore { toggleAll() { const select = this.selectedCount() !== this.store.issues.length; - this.store.issues.forEach((issue) => { + this.store.issues.forEach(issue => { const issueUpdate = issue; if (issueUpdate.selected !== select) { @@ -69,13 +69,14 @@ class ModalStore { removeSelectedIssue(issue, forcePurge = false) { if (this.store.activeTab === 'all' || forcePurge) { - this.store.selectedIssues = this.store.selectedIssues - .filter(fIssue => fIssue.id !== issue.id); + this.store.selectedIssues = this.store.selectedIssues.filter( + fIssue => fIssue.id !== issue.id, + ); } } purgeUnselectedIssues() { - this.store.selectedIssues.forEach((issue) => { + this.store.selectedIssues.forEach(issue => { if (!issue.selected) { this.removeSelectedIssue(issue, true); } @@ -87,8 +88,7 @@ class ModalStore { } findSelectedIssue(issue) { - return this.store.selectedIssues - .filter(filteredIssue => filteredIssue.id === issue.id)[0]; + return this.store.selectedIssues.filter(filteredIssue => filteredIssue.id === issue.id)[0]; } } diff --git a/app/assets/javascripts/commons/gitlab_ui.js b/app/assets/javascripts/commons/gitlab_ui.js index fe551480167..e93e1f5ea2c 100644 --- a/app/assets/javascripts/commons/gitlab_ui.js +++ b/app/assets/javascripts/commons/gitlab_ui.js @@ -1,9 +1,5 @@ import Vue from 'vue'; -import { - GlProgressBar, - GlLoadingIcon, - GlTooltipDirective, -} from '@gitlab-org/gitlab-ui'; +import { GlProgressBar, GlLoadingIcon, GlTooltipDirective } from '@gitlab-org/gitlab-ui'; Vue.component('gl-progress-bar', GlProgressBar); Vue.component('gl-loading-icon', GlLoadingIcon); diff --git a/app/assets/javascripts/diffs/components/tree_list.vue b/app/assets/javascripts/diffs/components/tree_list.vue index 96e7bd63183..91052b303a6 100644 --- a/app/assets/javascripts/diffs/components/tree_list.vue +++ b/app/assets/javascripts/diffs/components/tree_list.vue @@ -18,8 +18,8 @@ export default { }, data() { const treeListStored = localStorage.getItem(treeListStorageKey); - const renderTreeList = treeListStored !== null ? - convertPermissionToBoolean(treeListStored) : true; + const renderTreeList = + treeListStored !== null ? convertPermissionToBoolean(treeListStored) : true; return { search: '', diff --git a/app/assets/javascripts/environments/components/environments_app.vue b/app/assets/javascripts/environments/components/environments_app.vue index e2ecf426e64..557b2062c64 100644 --- a/app/assets/javascripts/environments/components/environments_app.vue +++ b/app/assets/javascripts/environments/components/environments_app.vue @@ -1,94 +1,92 @@ <script> - import Flash from '../../flash'; - import { s__ } from '../../locale'; - import emptyState from './empty_state.vue'; - import eventHub from '../event_hub'; - import environmentsMixin from '../mixins/environments_mixin'; - import CIPaginationMixin from '../../vue_shared/mixins/ci_pagination_api_mixin'; - import StopEnvironmentModal from './stop_environment_modal.vue'; +import Flash from '../../flash'; +import { s__ } from '../../locale'; +import emptyState from './empty_state.vue'; +import eventHub from '../event_hub'; +import environmentsMixin from '../mixins/environments_mixin'; +import CIPaginationMixin from '../../vue_shared/mixins/ci_pagination_api_mixin'; +import StopEnvironmentModal from './stop_environment_modal.vue'; - export default { - components: { - emptyState, - StopEnvironmentModal, - }, +export default { + components: { + emptyState, + StopEnvironmentModal, + }, - mixins: [ - CIPaginationMixin, - environmentsMixin, - ], + mixins: [CIPaginationMixin, environmentsMixin], - props: { - endpoint: { - type: String, - required: true, - }, - canCreateEnvironment: { - type: Boolean, - required: true, - }, - canCreateDeployment: { - type: Boolean, - required: true, - }, - canReadEnvironment: { - type: Boolean, - required: true, - }, - cssContainerClass: { - type: String, - required: true, - }, - newEnvironmentPath: { - type: String, - required: true, - }, - helpPagePath: { - type: String, - required: true, - }, + props: { + endpoint: { + type: String, + required: true, }, - - created() { - eventHub.$on('toggleFolder', this.toggleFolder); + canCreateEnvironment: { + type: Boolean, + required: true, }, - - beforeDestroy() { - eventHub.$off('toggleFolder'); + canCreateDeployment: { + type: Boolean, + required: true, + }, + canReadEnvironment: { + type: Boolean, + required: true, + }, + cssContainerClass: { + type: String, + required: true, + }, + newEnvironmentPath: { + type: String, + required: true, }, + helpPagePath: { + type: String, + required: true, + }, + }, + + created() { + eventHub.$on('toggleFolder', this.toggleFolder); + }, - methods: { - toggleFolder(folder) { - this.store.toggleFolder(folder); + beforeDestroy() { + eventHub.$off('toggleFolder'); + }, - if (!folder.isOpen) { - this.fetchChildEnvironments(folder, true); - } - }, + methods: { + toggleFolder(folder) { + this.store.toggleFolder(folder); - fetchChildEnvironments(folder, showLoader = false) { - this.store.updateEnvironmentProp(folder, 'isLoadingFolderContent', showLoader); + if (!folder.isOpen) { + this.fetchChildEnvironments(folder, true); + } + }, - this.service.getFolderContent(folder.folder_path) - .then(response => this.store.setfolderContent(folder, response.data.environments)) - .then(() => this.store.updateEnvironmentProp(folder, 'isLoadingFolderContent', false)) - .catch(() => { - Flash(s__('Environments|An error occurred while fetching the environments.')); - this.store.updateEnvironmentProp(folder, 'isLoadingFolderContent', false); - }); - }, + fetchChildEnvironments(folder, showLoader = false) { + this.store.updateEnvironmentProp(folder, 'isLoadingFolderContent', showLoader); + + this.service + .getFolderContent(folder.folder_path) + .then(response => this.store.setfolderContent(folder, response.data.environments)) + .then(() => this.store.updateEnvironmentProp(folder, 'isLoadingFolderContent', false)) + .catch(() => { + Flash(s__('Environments|An error occurred while fetching the environments.')); + this.store.updateEnvironmentProp(folder, 'isLoadingFolderContent', false); + }); + }, - successCallback(resp) { - this.saveData(resp); + successCallback(resp) { + this.saveData(resp); - // We need to verify if any folder is open to also update it - const openFolders = this.store.getOpenFolders(); - if (openFolders.length) { - openFolders.forEach(folder => this.fetchChildEnvironments(folder)); - } - }, + // We need to verify if any folder is open to also update it + const openFolders = this.store.getOpenFolders(); + if (openFolders.length) { + openFolders.forEach(folder => this.fetchChildEnvironments(folder)); + } }, - }; + }, +}; </script> <template> <div :class="cssContainerClass"> diff --git a/app/assets/javascripts/environments/stores/environments_store.js b/app/assets/javascripts/environments/stores/environments_store.js index 5ce9225a4bb..5808a2d4afa 100644 --- a/app/assets/javascripts/environments/stores/environments_store.js +++ b/app/assets/javascripts/environments/stores/environments_store.js @@ -34,14 +34,14 @@ export default class EnvironmentsStore { * @returns {Array} */ storeEnvironments(environments = []) { - const filteredEnvironments = environments.map((env) => { - const oldEnvironmentState = this.state.environments - .find((element) => { - if (env.latest) { - return element.id === env.latest.id; - } - return element.id === env.id; - }) || {}; + const filteredEnvironments = environments.map(env => { + const oldEnvironmentState = + this.state.environments.find(element => { + if (env.latest) { + return element.id === env.latest.id; + } + return element.id === env.id; + }) || {}; let filtered = {}; @@ -101,11 +101,11 @@ export default class EnvironmentsStore { } /** - * Toggles folder open property for the given folder. - * - * @param {Object} folder - * @return {Array} - */ + * Toggles folder open property for the given folder. + * + * @param {Object} folder + * @return {Array} + */ toggleFolder(folder) { return this.updateEnvironmentProp(folder, 'isOpen', !folder.isOpen); } @@ -119,7 +119,7 @@ export default class EnvironmentsStore { * @return {Object} */ setfolderContent(folder, environments) { - const updatedEnvironments = environments.map((env) => { + const updatedEnvironments = environments.map(env => { let updated = env; if (env.latest) { @@ -148,7 +148,7 @@ export default class EnvironmentsStore { updateEnvironmentProp(environment, prop, newValue) { const { environments } = this.state; - const updatedEnvironments = environments.map((env) => { + const updatedEnvironments = environments.map(env => { const updateEnv = Object.assign({}, env); if (env.id === environment.id) { updateEnv[prop] = newValue; diff --git a/app/assets/javascripts/filtered_search/dropdown_user.js b/app/assets/javascripts/filtered_search/dropdown_user.js index d36f38a70b5..d5027590bb7 100644 --- a/app/assets/javascripts/filtered_search/dropdown_user.js +++ b/app/assets/javascripts/filtered_search/dropdown_user.js @@ -39,8 +39,9 @@ export default class DropdownUser extends FilteredSearchDropdown { } itemClicked(e) { - super.itemClicked(e, - selected => selected.querySelector('.dropdown-light-content').innerText.trim()); + super.itemClicked(e, selected => + selected.querySelector('.dropdown-light-content').innerText.trim(), + ); } renderContent(forceShowList = false) { @@ -68,7 +69,7 @@ export default class DropdownUser extends FilteredSearchDropdown { // Removes the first character if it is a quotation so that we can search // with multiple words - if (value[0] === '"' || value[0] === '\'') { + if (value[0] === '"' || value[0] === "'") { value = value.slice(1); } diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js index cd3d532c958..57ec6603d80 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js @@ -108,7 +108,7 @@ export default class FilteredSearchDropdownManager { }, }; - supportedTokens.forEach((type) => { + supportedTokens.forEach(type => { if (availableMappings[type]) { allowedMappings[type] = availableMappings[type]; } @@ -142,10 +142,7 @@ export default class FilteredSearchDropdownManager { } static addWordToInput(tokenName, tokenValue = '', clicked = false, options = {}) { - const { - uppercaseTokenName = false, - capitalizeTokenValue = false, - } = options; + const { uppercaseTokenName = false, capitalizeTokenValue = false } = options; const input = FilteredSearchContainer.container.querySelector('.filtered-search'); FilteredSearchVisualTokens.addFilterVisualToken(tokenName, tokenValue, { uppercaseTokenName, @@ -164,13 +161,16 @@ export default class FilteredSearchDropdownManager { updateDropdownOffset(key) { // Always align dropdown with the input field - let offset = this.filteredSearchInput.getBoundingClientRect().left - this.container.querySelector('.scroll-container').getBoundingClientRect().left; + let offset = + this.filteredSearchInput.getBoundingClientRect().left - + this.container.querySelector('.scroll-container').getBoundingClientRect().left; const maxInputWidth = 240; const currentDropdownWidth = this.mapping[key].element.clientWidth || maxInputWidth; // Make sure offset never exceeds the input container - const offsetMaxWidth = this.container.querySelector('.scroll-container').clientWidth - currentDropdownWidth; + const offsetMaxWidth = + this.container.querySelector('.scroll-container').clientWidth - currentDropdownWidth; if (offsetMaxWidth < offset) { offset = offsetMaxWidth; } @@ -196,8 +196,7 @@ export default class FilteredSearchDropdownManager { const glArguments = Object.assign({}, defaultArguments, extraArguments); // Passing glArguments to `new glClass(<arguments>)` - mappingKey.reference = - new (Function.prototype.bind.apply(glClass, [null, glArguments]))(); + mappingKey.reference = new (Function.prototype.bind.apply(glClass, [null, glArguments]))(); } if (firstLoad) { @@ -224,8 +223,8 @@ export default class FilteredSearchDropdownManager { } const match = this.filteredSearchTokenKeys.searchByKey(dropdownName.toLowerCase()); - const shouldOpenFilterDropdown = match && this.currentDropdown !== match.key - && this.mapping[match.key]; + const shouldOpenFilterDropdown = + match && this.currentDropdown !== match.key && this.mapping[match.key]; const shouldOpenHintDropdown = !match && this.currentDropdown !== 'hint'; if (shouldOpenFilterDropdown || shouldOpenHintDropdown) { @@ -236,8 +235,10 @@ export default class FilteredSearchDropdownManager { setDropdown() { const query = DropdownUtils.getSearchQuery(true); - const { lastToken, searchToken } = - this.tokenizer.processTokens(query, this.filteredSearchTokenKeys.getKeys()); + const { lastToken, searchToken } = this.tokenizer.processTokens( + query, + this.filteredSearchTokenKeys.getKeys(), + ); if (this.currentDropdown) { this.updateCurrentDropdownOffset(); diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js b/app/assets/javascripts/filtered_search/filtered_search_manager.js index 54533ebb70d..4a2af02b40a 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_manager.js +++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js @@ -1,8 +1,5 @@ import _ from 'underscore'; -import { - getParameterByName, - getUrlParamsArray, -} from '~/lib/utils/common_utils'; +import { getParameterByName, getUrlParamsArray } from '~/lib/utils/common_utils'; import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys'; import { visitUrl } from '../lib/utils/url_utility'; import Flash from '../flash'; @@ -48,24 +45,28 @@ export default class FilteredSearchManager { isLocalStorageAvailable: RecentSearchesService.isAvailable(), allowedKeys: this.filteredSearchTokenKeys.getKeys(), }); - this.searchHistoryDropdownElement = document.querySelector('.js-filtered-search-history-dropdown'); - const fullPath = this.searchHistoryDropdownElement ? - this.searchHistoryDropdownElement.dataset.fullPath : 'project'; + this.searchHistoryDropdownElement = document.querySelector( + '.js-filtered-search-history-dropdown', + ); + const fullPath = this.searchHistoryDropdownElement + ? this.searchHistoryDropdownElement.dataset.fullPath + : 'project'; const recentSearchesKey = `${fullPath}-${this.recentsStorageKeyNames[this.page]}`; this.recentSearchesService = new RecentSearchesService(recentSearchesKey); } setup() { // Fetch recent searches from localStorage - this.fetchingRecentSearchesPromise = this.recentSearchesService.fetch() - .catch((error) => { + this.fetchingRecentSearchesPromise = this.recentSearchesService + .fetch() + .catch(error => { if (error.name === 'RecentSearchesServiceError') return undefined; // eslint-disable-next-line no-new new Flash('An error occurred while parsing recent searches'); // Gracefully fail to empty array return []; }) - .then((searches) => { + .then(searches => { if (!searches) { return; } @@ -120,7 +121,7 @@ export default class FilteredSearchManager { if (this.stateFilters) { this.searchStateWrapper = this.searchState.bind(this); - this.applyToStateFilters((filterEl) => { + this.applyToStateFilters(filterEl => { filterEl.addEventListener('click', this.searchStateWrapper); }); } @@ -128,14 +129,14 @@ export default class FilteredSearchManager { unbindStateEvents() { if (this.stateFilters) { - this.applyToStateFilters((filterEl) => { + this.applyToStateFilters(filterEl => { filterEl.removeEventListener('click', this.searchStateWrapper); }); } } applyToStateFilters(callback) { - this.stateFilters.querySelectorAll('a[data-state]').forEach((filterEl) => { + this.stateFilters.querySelectorAll('a[data-state]').forEach(filterEl => { if (this.states.indexOf(filterEl.dataset.state) > -1) { callback(filterEl); } @@ -207,7 +208,7 @@ export default class FilteredSearchManager { let backspaceCount = 0; // closure for keeping track of the number of backspace keystrokes - return (e) => { + return e => { // 8 = Backspace Key // 46 = Delete Key if (e.keyCode === 8 || e.keyCode === 46) { @@ -274,8 +275,12 @@ export default class FilteredSearchManager { const isElementInDynamicFilterDropdown = e.target.closest('.filter-dropdown') !== null; const isElementInStaticFilterDropdown = e.target.closest('ul[data-dropdown]') !== null; - if (!isElementInFilteredSearch && !isElementInDynamicFilterDropdown && - !isElementInStaticFilterDropdown && inputContainer) { + if ( + !isElementInFilteredSearch && + !isElementInDynamicFilterDropdown && + !isElementInStaticFilterDropdown && + inputContainer + ) { inputContainer.classList.remove('focus'); } } @@ -368,7 +373,7 @@ export default class FilteredSearchManager { const removeElements = []; - [].forEach.call(this.tokensContainer.children, (t) => { + [].forEach.call(this.tokensContainer.children, t => { let canClearToken = t.classList.contains('js-visual-token'); if (canClearToken) { @@ -381,7 +386,7 @@ export default class FilteredSearchManager { } }); - removeElements.forEach((el) => { + removeElements.forEach(el => { el.parentElement.removeChild(el); }); @@ -397,13 +402,14 @@ export default class FilteredSearchManager { handleInputVisualToken() { const input = this.filteredSearchInput; - const { tokens, searchToken } - = this.tokenizer.processTokens(input.value, this.filteredSearchTokenKeys.getKeys()); - const { isLastVisualTokenValid } - = FilteredSearchVisualTokens.getLastVisualTokenBeforeInput(); + const { tokens, searchToken } = this.tokenizer.processTokens( + input.value, + this.filteredSearchTokenKeys.getKeys(), + ); + const { isLastVisualTokenValid } = FilteredSearchVisualTokens.getLastVisualTokenBeforeInput(); if (isLastVisualTokenValid) { - tokens.forEach((t) => { + tokens.forEach(t => { input.value = input.value.replace(`${t.key}:${t.symbol}${t.value}`, ''); FilteredSearchVisualTokens.addFilterVisualToken(t.key, `${t.symbol}${t.value}`, { uppercaseTokenName: this.filteredSearchTokenKeys.shouldUppercaseTokenName(t.key), @@ -453,15 +459,17 @@ export default class FilteredSearchManager { saveCurrentSearchQuery() { // Don't save before we have fetched the already saved searches - this.fetchingRecentSearchesPromise.then(() => { - const searchQuery = DropdownUtils.getSearchQuery(); - if (searchQuery.length > 0) { - const resultantSearches = this.recentSearchesStore.addRecentSearch(searchQuery); - this.recentSearchesService.save(resultantSearches); - } - }).catch(() => { - // https://gitlab.com/gitlab-org/gitlab-ce/issues/30821 - }); + this.fetchingRecentSearchesPromise + .then(() => { + const searchQuery = DropdownUtils.getSearchQuery(); + if (searchQuery.length > 0) { + const resultantSearches = this.recentSearchesStore.addRecentSearch(searchQuery); + this.recentSearchesService.save(resultantSearches); + } + }) + .catch(() => { + // https://gitlab.com/gitlab-org/gitlab-ce/issues/30821 + }); } // allows for modifying params array when a param can't be included in the URL (e.g. Service Desk) @@ -475,7 +483,7 @@ export default class FilteredSearchManager { const usernameParams = this.getUsernameParams(); let hasFilteredSearch = false; - params.forEach((p) => { + params.forEach(p => { const split = p.split('='); const keyParam = decodeURIComponent(split[0]); const value = split[1]; @@ -486,11 +494,9 @@ export default class FilteredSearchManager { if (condition) { hasFilteredSearch = true; const canEdit = this.canEdit && this.canEdit(condition.tokenKey); - FilteredSearchVisualTokens.addFilterVisualToken( - condition.tokenKey, - condition.value, - { canEdit }, - ); + FilteredSearchVisualTokens.addFilterVisualToken(condition.tokenKey, condition.value, { + canEdit, + }); } else { // Sanitize value since URL converts spaces into + // Replace before decode so that we know what was originally + versus the encoded + @@ -510,7 +516,7 @@ export default class FilteredSearchManager { if (sanitizedValue.indexOf(' ') !== -1) { // Prefer ", but use ' if required - quotationsToUse = sanitizedValue.indexOf('"') === -1 ? '"' : '\''; + quotationsToUse = sanitizedValue.indexOf('"') === -1 ? '"' : "'"; } hasFilteredSearch = true; @@ -531,7 +537,9 @@ export default class FilteredSearchManager { hasFilteredSearch = true; const tokenName = 'assignee'; const canEdit = this.canEdit && this.canEdit(tokenName); - FilteredSearchVisualTokens.addFilterVisualToken(tokenName, `@${usernameParams[id]}`, { canEdit }); + FilteredSearchVisualTokens.addFilterVisualToken(tokenName, `@${usernameParams[id]}`, { + canEdit, + }); } } else if (!match && keyParam === 'author_id') { const id = parseInt(value, 10); @@ -539,7 +547,9 @@ export default class FilteredSearchManager { hasFilteredSearch = true; const tokenName = 'author'; const canEdit = this.canEdit && this.canEdit(tokenName); - FilteredSearchVisualTokens.addFilterVisualToken(tokenName, `@${usernameParams[id]}`, { canEdit }); + FilteredSearchVisualTokens.addFilterVisualToken(tokenName, `@${usernameParams[id]}`, { + canEdit, + }); } } else if (!match && keyParam === 'search') { hasFilteredSearch = true; @@ -580,9 +590,11 @@ export default class FilteredSearchManager { const currentState = state || getParameterByName('state') || 'opened'; paths.push(`state=${currentState}`); - tokens.forEach((token) => { - const condition = this.filteredSearchTokenKeys - .searchByConditionKeyValue(token.key, token.value.toLowerCase()); + tokens.forEach(token => { + const condition = this.filteredSearchTokenKeys.searchByConditionKeyValue( + token.key, + token.value.toLowerCase(), + ); const tokenConfig = this.filteredSearchTokenKeys.searchByKey(token.key) || {}; const { param } = tokenConfig; @@ -601,8 +613,10 @@ export default class FilteredSearchManager { tokenValue = tokenValue.toLowerCase(); } - if ((tokenValue[0] === '\'' && tokenValue[tokenValue.length - 1] === '\'') || - (tokenValue[0] === '"' && tokenValue[tokenValue.length - 1] === '"')) { + if ( + (tokenValue[0] === "'" && tokenValue[tokenValue.length - 1] === "'") || + (tokenValue[0] === '"' && tokenValue[tokenValue.length - 1] === '"') + ) { tokenValue = tokenValue.slice(1, tokenValue.length - 1); } @@ -613,7 +627,10 @@ export default class FilteredSearchManager { }); if (searchToken) { - const sanitized = searchToken.split(' ').map(t => encodeURIComponent(t)).join('+'); + const sanitized = searchToken + .split(' ') + .map(t => encodeURIComponent(t)) + .join('+'); paths.push(`search=${sanitized}`); } @@ -630,7 +647,7 @@ export default class FilteredSearchManager { const usernamesById = {}; try { const attribute = this.filteredSearchInput.getAttribute('data-username-params'); - JSON.parse(attribute).forEach((user) => { + JSON.parse(attribute).forEach(user => { usernamesById[user.id] = user.username; }); } catch (e) { diff --git a/app/assets/javascripts/flash.js b/app/assets/javascripts/flash.js index 749c09f897c..c2397842125 100644 --- a/app/assets/javascripts/flash.js +++ b/app/assets/javascripts/flash.js @@ -40,7 +40,9 @@ const createFlashEl = (message, type, isFixedLayout = false) => ` class="flash-${type}" > <div - class="flash-text ${isFixedLayout ? 'container-fluid container-limited limit-container-width' : ''}" + class="flash-text ${ + isFixedLayout ? 'container-fluid container-limited limit-container-width' : '' + }" > ${_.escape(message)} </div> @@ -78,7 +80,9 @@ const createFlash = function createFlash( if (!flashContainer) return null; - const isFixedLayout = navigation ? navigation.parentNode.classList.contains('container-limited') : true; + const isFixedLayout = navigation + ? navigation.parentNode.classList.contains('container-limited') + : true; flashContainer.innerHTML = createFlashEl(message, type, isFixedLayout); diff --git a/app/assets/javascripts/gfm_auto_complete.js b/app/assets/javascripts/gfm_auto_complete.js index 7dd0efd622d..8f18aadb5e9 100644 --- a/app/assets/javascripts/gfm_auto_complete.js +++ b/app/assets/javascripts/gfm_auto_complete.js @@ -94,7 +94,7 @@ class GfmAutoComplete { ...this.getDefaultCallbacks(), beforeSave(commands) { if (GfmAutoComplete.isLoading(commands)) return commands; - return $.map(commands, (c) => { + return $.map(commands, c => { let search = c.name; if (c.aliases.length > 0) { search = `${search} ${c.aliases.join(' ')}`; @@ -167,7 +167,7 @@ class GfmAutoComplete { callbacks: { ...this.getDefaultCallbacks(), beforeSave(members) { - return $.map(members, (m) => { + return $.map(members, m => { let title = ''; if (m.username == null) { return m; @@ -178,7 +178,9 @@ class GfmAutoComplete { } const autoCompleteAvatar = m.avatar_url || m.username.charAt(0).toUpperCase(); - const imgAvatar = `<img src="${m.avatar_url}" alt="${m.username}" class="avatar avatar-inline center s26"/>`; + const imgAvatar = `<img src="${m.avatar_url}" alt="${ + m.username + }" class="avatar avatar-inline center s26"/>`; const txtAvatar = `<div class="avatar center avatar-inline s26">${autoCompleteAvatar}</div>`; return { @@ -211,7 +213,7 @@ class GfmAutoComplete { callbacks: { ...this.getDefaultCallbacks(), beforeSave(issues) { - return $.map(issues, (i) => { + return $.map(issues, i => { if (i.title == null) { return i; } @@ -244,7 +246,7 @@ class GfmAutoComplete { callbacks: { ...this.getDefaultCallbacks(), beforeSave(milestones) { - return $.map(milestones, (m) => { + return $.map(milestones, m => { if (m.title == null) { return m; } @@ -277,7 +279,7 @@ class GfmAutoComplete { callbacks: { ...this.getDefaultCallbacks(), beforeSave(merges) { - return $.map(merges, (m) => { + return $.map(merges, m => { if (m.title == null) { return m; } @@ -324,13 +326,20 @@ class GfmAutoComplete { }, matcher(flag, subtext) { const match = GfmAutoComplete.defaultMatcher(flag, subtext, this.app.controllers); - const subtextNodes = subtext.split(/\n+/g).pop().split(GfmAutoComplete.regexSubtext); + const subtextNodes = subtext + .split(/\n+/g) + .pop() + .split(GfmAutoComplete.regexSubtext); // Check if ~ is followed by '/label', '/relabel' or '/unlabel' commands. - command = subtextNodes.find((node) => { - if (node === LABEL_COMMAND.LABEL || - node === LABEL_COMMAND.RELABEL || - node === LABEL_COMMAND.UNLABEL) { return node; } + command = subtextNodes.find(node => { + if ( + node === LABEL_COMMAND.LABEL || + node === LABEL_COMMAND.RELABEL || + node === LABEL_COMMAND.UNLABEL + ) { + return node; + } return null; }); @@ -380,7 +389,7 @@ class GfmAutoComplete { callbacks: { ...this.getDefaultCallbacks(), beforeSave(snippets) { - return $.map(snippets, (m) => { + return $.map(snippets, m => { if (m.title == null) { return m; } @@ -458,13 +467,17 @@ class GfmAutoComplete { this.loadData($input, at, validEmojiNames); GfmAutoComplete.glEmojiTag = glEmojiTag; }) - .catch(() => { this.isLoadingData[at] = false; }); + .catch(() => { + this.isLoadingData[at] = false; + }); } else if (dataSource) { AjaxCache.retrieve(dataSource, true) - .then((data) => { + .then(data => { this.loadData($input, at, data); }) - .catch(() => { this.isLoadingData[at] = false; }); + .catch(() => { + this.isLoadingData[at] = false; + }); } else { this.isLoadingData[at] = false; } @@ -497,15 +510,16 @@ class GfmAutoComplete { } const loadingState = GfmAutoComplete.defaultLoadingData[0]; - return dataToInspect && - (dataToInspect === loadingState || dataToInspect.name === loadingState); + return dataToInspect && (dataToInspect === loadingState || dataToInspect.name === loadingState); } static defaultMatcher(flag, subtext, controllers) { // The below is taken from At.js source // Tweaked to commands to start without a space only if char before is a non-word character // https://github.com/ichord/At.js - const atSymbolsWithBar = Object.keys(controllers).join('|').replace(/[$]/, '\\$&'); + const atSymbolsWithBar = Object.keys(controllers) + .join('|') + .replace(/[$]/, '\\$&'); const atSymbolsWithoutBar = Object.keys(controllers).join(''); const targetSubtext = subtext.split(GfmAutoComplete.regexSubtext).pop(); const resultantFlag = flag.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&'); @@ -513,7 +527,10 @@ class GfmAutoComplete { const accentAChar = decodeURI('%C3%80'); const accentYChar = decodeURI('%C3%BF'); - const regexp = new RegExp(`^(?:\\B|[^a-zA-Z0-9_\`${atSymbolsWithoutBar}]|\\s)${resultantFlag}(?!${atSymbolsWithBar})((?:[A-Za-z${accentAChar}-${accentYChar}0-9_'.+-]|[^\\x00-\\x7a])*)$`, 'gi'); + const regexp = new RegExp( + `^(?:\\B|[^a-zA-Z0-9_\`${atSymbolsWithoutBar}]|\\s)${resultantFlag}(?!${atSymbolsWithBar})((?:[A-Za-z${accentAChar}-${accentYChar}0-9_'.+-]|[^\\x00-\\x7a])*)$`, + 'gi', + ); return regexp.exec(targetSubtext); } @@ -553,7 +570,8 @@ GfmAutoComplete.Members = { }; GfmAutoComplete.Labels = { // eslint-disable-next-line no-template-curly-in-string - template: '<li><span class="dropdown-label-box" style="background: ${color}"></span> ${title}</li>', + template: + '<li><span class="dropdown-label-box" style="background: ${color}"></span> ${title}</li>', }; // Issues, MergeRequests and Snippets GfmAutoComplete.Issues = { @@ -567,7 +585,8 @@ GfmAutoComplete.Milestones = { template: '<li>${title}</li>', }; GfmAutoComplete.Loading = { - template: '<li style="pointer-events: none;"><i class="fa fa-spinner fa-spin"></i> Loading...</li>', + template: + '<li style="pointer-events: none;"><i class="fa fa-spinner fa-spin"></i> Loading...</li>', }; export default GfmAutoComplete; diff --git a/app/assets/javascripts/jobs/components/job_app.vue b/app/assets/javascripts/jobs/components/job_app.vue index ac19034f69d..3cabbfc6e27 100644 --- a/app/assets/javascripts/jobs/components/job_app.vue +++ b/app/assets/javascripts/jobs/components/job_app.vue @@ -1,164 +1,164 @@ <script> - import _ from 'underscore'; - import { mapGetters, mapState, mapActions } from 'vuex'; - import { isScrolledToBottom } from '~/lib/utils/scroll_utils'; - import bp from '~/breakpoints'; - import CiHeader from '~/vue_shared/components/header_ci_component.vue'; - import Callout from '~/vue_shared/components/callout.vue'; - import createStore from '../store'; - import EmptyState from './empty_state.vue'; - import EnvironmentsBlock from './environments_block.vue'; - import ErasedBlock from './erased_block.vue'; - import Log from './job_log.vue'; - import LogTopBar from './job_log_controllers.vue'; - import StuckBlock from './stuck_block.vue'; - import Sidebar from './sidebar.vue'; +import _ from 'underscore'; +import { mapGetters, mapState, mapActions } from 'vuex'; +import { isScrolledToBottom } from '~/lib/utils/scroll_utils'; +import bp from '~/breakpoints'; +import CiHeader from '~/vue_shared/components/header_ci_component.vue'; +import Callout from '~/vue_shared/components/callout.vue'; +import createStore from '../store'; +import EmptyState from './empty_state.vue'; +import EnvironmentsBlock from './environments_block.vue'; +import ErasedBlock from './erased_block.vue'; +import Log from './job_log.vue'; +import LogTopBar from './job_log_controllers.vue'; +import StuckBlock from './stuck_block.vue'; +import Sidebar from './sidebar.vue'; - export default { - name: 'JobPageApp', - store: createStore(), - components: { - CiHeader, - Callout, - EmptyState, - EnvironmentsBlock, - ErasedBlock, - Log, - LogTopBar, - StuckBlock, - Sidebar, +export default { + name: 'JobPageApp', + store: createStore(), + components: { + CiHeader, + Callout, + EmptyState, + EnvironmentsBlock, + ErasedBlock, + Log, + LogTopBar, + StuckBlock, + Sidebar, + }, + props: { + runnerSettingsUrl: { + type: String, + required: false, + default: null, }, - props: { - runnerSettingsUrl: { - type: String, - required: false, - default: null, - }, - runnerHelpUrl: { - type: String, - required: false, - default: null, - }, - endpoint: { - type: String, - required: true, - }, - terminalPath: { - type: String, - required: false, - default: null, - }, - pagePath: { - type: String, - required: true, - }, - logState: { - type: String, - required: true, - }, + runnerHelpUrl: { + type: String, + required: false, + default: null, }, - computed: { - ...mapState([ - 'isLoading', - 'job', - 'isSidebarOpen', - 'trace', - 'isTraceComplete', - 'traceSize', - 'isTraceSizeVisible', - 'isScrollBottomDisabled', - 'isScrollTopDisabled', - 'isScrolledToBottomBeforeReceivingTrace', - 'hasError', - ]), - ...mapGetters([ - 'headerActions', - 'headerTime', - 'shouldRenderCalloutMessage', - 'shouldRenderTriggeredLabel', - 'hasEnvironment', - 'hasTrace', - 'emptyStateIllustration', - 'isScrollingDown', - 'emptyStateAction', - 'hasRunnersForProject', - ]), + endpoint: { + type: String, + required: true, + }, + terminalPath: { + type: String, + required: false, + default: null, + }, + pagePath: { + type: String, + required: true, + }, + logState: { + type: String, + required: true, + }, + }, + computed: { + ...mapState([ + 'isLoading', + 'job', + 'isSidebarOpen', + 'trace', + 'isTraceComplete', + 'traceSize', + 'isTraceSizeVisible', + 'isScrollBottomDisabled', + 'isScrollTopDisabled', + 'isScrolledToBottomBeforeReceivingTrace', + 'hasError', + ]), + ...mapGetters([ + 'headerActions', + 'headerTime', + 'shouldRenderCalloutMessage', + 'shouldRenderTriggeredLabel', + 'hasEnvironment', + 'hasTrace', + 'emptyStateIllustration', + 'isScrollingDown', + 'emptyStateAction', + 'hasRunnersForProject', + ]), - shouldRenderContent() { - return !this.isLoading && !this.hasError; - } + shouldRenderContent() { + return !this.isLoading && !this.hasError; }, - watch: { - // Once the job log is loaded, - // fetch the stages for the dropdown on the sidebar - job(newVal, oldVal) { - if (_.isEmpty(oldVal) && !_.isEmpty(newVal.pipeline)) { - this.fetchStages(); - } - }, + }, + watch: { + // Once the job log is loaded, + // fetch the stages for the dropdown on the sidebar + job(newVal, oldVal) { + if (_.isEmpty(oldVal) && !_.isEmpty(newVal.pipeline)) { + this.fetchStages(); + } }, - created() { - this.throttled = _.throttle(this.toggleScrollButtons, 100); + }, + created() { + this.throttled = _.throttle(this.toggleScrollButtons, 100); - this.setJobEndpoint(this.endpoint); - this.setTraceOptions({ - logState: this.logState, - pagePath: this.pagePath, - }); + this.setJobEndpoint(this.endpoint); + this.setTraceOptions({ + logState: this.logState, + pagePath: this.pagePath, + }); - this.fetchJob(); - this.fetchTrace(); + this.fetchJob(); + this.fetchTrace(); - window.addEventListener('resize', this.onResize); - window.addEventListener('scroll', this.updateScroll); - }, + window.addEventListener('resize', this.onResize); + window.addEventListener('scroll', this.updateScroll); + }, - mounted() { + mounted() { + this.updateSidebar(); + }, + + destroyed() { + window.removeEventListener('resize', this.onResize); + window.removeEventListener('scroll', this.updateScroll); + }, + + methods: { + ...mapActions([ + 'setJobEndpoint', + 'setTraceOptions', + 'fetchJob', + 'fetchStages', + 'hideSidebar', + 'showSidebar', + 'toggleSidebar', + 'fetchTrace', + 'scrollBottom', + 'scrollTop', + 'toggleScrollButtons', + 'toggleScrollAnimation', + ]), + onResize() { this.updateSidebar(); + this.updateScroll(); }, - - destroyed() { - window.removeEventListener('resize', this.onResize); - window.removeEventListener('scroll', this.updateScroll); + updateSidebar() { + if (bp.getBreakpointSize() === 'xs') { + this.hideSidebar(); + } else if (!this.isSidebarOpen) { + this.showSidebar(); + } }, + updateScroll() { + if (!isScrolledToBottom()) { + this.toggleScrollAnimation(false); + } else if (this.isScrollingDown) { + this.toggleScrollAnimation(true); + } - methods: { - ...mapActions([ - 'setJobEndpoint', - 'setTraceOptions', - 'fetchJob', - 'fetchStages', - 'hideSidebar', - 'showSidebar', - 'toggleSidebar', - 'fetchTrace', - 'scrollBottom', - 'scrollTop', - 'toggleScrollButtons', - 'toggleScrollAnimation', - ]), - onResize() { - this.updateSidebar(); - this.updateScroll(); - }, - updateSidebar() { - if (bp.getBreakpointSize() === 'xs') { - this.hideSidebar(); - } else if (!this.isSidebarOpen) { - this.showSidebar(); - } - }, - updateScroll() { - if (!isScrolledToBottom()) { - this.toggleScrollAnimation(false); - } else if (this.isScrollingDown) { - this.toggleScrollAnimation(true); - } - - this.throttled(); - }, + this.throttled(); }, - }; + }, +}; </script> <template> <div> diff --git a/app/assets/javascripts/jobs/components/job_log.vue b/app/assets/javascripts/jobs/components/job_log.vue index ffa6ada3e28..92e20e92d66 100644 --- a/app/assets/javascripts/jobs/components/job_log.vue +++ b/app/assets/javascripts/jobs/components/job_log.vue @@ -1,45 +1,45 @@ <script> - import { mapState, mapActions } from 'vuex'; +import { mapState, mapActions } from 'vuex'; - export default { - name: 'JobLog', - props: { - trace: { - type: String, - required: true, - }, - isComplete: { - type: Boolean, - required: true, - }, +export default { + name: 'JobLog', + props: { + trace: { + type: String, + required: true, }, - computed: { - ...mapState(['isScrolledToBottomBeforeReceivingTrace']), + isComplete: { + type: Boolean, + required: true, }, - updated() { - this.$nextTick(() => this.handleScrollDown()); + }, + computed: { + ...mapState(['isScrolledToBottomBeforeReceivingTrace']), + }, + updated() { + this.$nextTick(() => this.handleScrollDown()); + }, + mounted() { + this.$nextTick(() => this.handleScrollDown()); + }, + methods: { + ...mapActions(['scrollBottom']), + /** + * The job log is sent in HTML, which means we need to use `v-html` to render it + * Using the updated hook with $nextTick is not enough to wait for the DOM to be updated + * in this case because it runs before `v-html` has finished running, since there's no + * Vue binding. + * In order to scroll the page down after `v-html` has finished, we need to use setTimeout + */ + handleScrollDown() { + if (this.isScrolledToBottomBeforeReceivingTrace) { + setTimeout(() => { + this.scrollBottom(); + }, 0); + } }, - mounted() { - this.$nextTick(() => this.handleScrollDown()); - }, - methods: { - ...mapActions(['scrollBottom']), - /** - * The job log is sent in HTML, which means we need to use `v-html` to render it - * Using the updated hook with $nextTick is not enough to wait for the DOM to be updated - * in this case because it runs before `v-html` has finished running, since there's no - * Vue binding. - * In order to scroll the page down after `v-html` has finished, we need to use setTimeout - */ - handleScrollDown() { - if (this.isScrolledToBottomBeforeReceivingTrace) { - setTimeout(() => { - this.scrollBottom(); - }, 0); - } - }, - }, - }; + }, +}; </script> <template> <pre class="js-build-trace build-trace qa-build-trace"> diff --git a/app/assets/javascripts/jobs/index.js b/app/assets/javascripts/jobs/index.js index ccd096a1da5..a32e945627c 100644 --- a/app/assets/javascripts/jobs/index.js +++ b/app/assets/javascripts/jobs/index.js @@ -23,4 +23,3 @@ export default () => { }, }); }; - diff --git a/app/assets/javascripts/jobs/store/getters.js b/app/assets/javascripts/jobs/store/getters.js index 4de01f8e532..d440b2c9ef1 100644 --- a/app/assets/javascripts/jobs/store/getters.js +++ b/app/assets/javascripts/jobs/store/getters.js @@ -35,16 +35,19 @@ export const hasEnvironment = state => !_.isEmpty(state.job.deployment_status); * Used to check if it should render the job log or the empty state * @returns {Boolean} */ -export const hasTrace = state => state.job.has_trace || (!_.isEmpty(state.job.status) && state.job.status.group === 'running'); +export const hasTrace = state => + state.job.has_trace || (!_.isEmpty(state.job.status) && state.job.status.group === 'running'); export const emptyStateIllustration = state => (state.job && state.job.status && state.job.status.illustration) || {}; -export const emptyStateAction = state => (state.job && state.job.status && state.job.status.action) || {}; +export const emptyStateAction = state => + (state.job && state.job.status && state.job.status.action) || {}; export const isScrollingDown = state => isScrolledToBottom() && !state.isTraceComplete; -export const hasRunnersForProject = state => state.job.runners.available && !state.job.runners.online; +export const hasRunnersForProject = state => + state.job.runners.available && !state.job.runners.online; // prevent babel-plugin-rewire from generating an invalid default during karma tests export default () => {}; diff --git a/app/assets/javascripts/labels_select.js b/app/assets/javascripts/labels_select.js index 3c38d998b6c..5457604b3b9 100644 --- a/app/assets/javascripts/labels_select.js +++ b/app/assets/javascripts/labels_select.js @@ -25,7 +25,35 @@ export default class LabelsSelect { } $els.each(function(i, dropdown) { - var $block, $colorPreview, $dropdown, $form, $loading, $selectbox, $sidebarCollapsedValue, $value, abilityName, defaultLabel, enableLabelCreateButton, issueURLSplit, issueUpdateURL, labelUrl, namespacePath, projectPath, saveLabelData, selectedLabel, showAny, showNo, $sidebarLabelTooltip, initialSelected, $toggleText, fieldName, useId, propertyName, showMenuAbove, $container, $dropdownContainer; + var $block, + $colorPreview, + $dropdown, + $form, + $loading, + $selectbox, + $sidebarCollapsedValue, + $value, + abilityName, + defaultLabel, + enableLabelCreateButton, + issueURLSplit, + issueUpdateURL, + labelUrl, + namespacePath, + projectPath, + saveLabelData, + selectedLabel, + showAny, + showNo, + $sidebarLabelTooltip, + initialSelected, + $toggleText, + fieldName, + useId, + propertyName, + showMenuAbove, + $container, + $dropdownContainer; $dropdown = $(dropdown); $dropdownContainer = $dropdown.closest('.labels-filter'); $toggleText = $dropdown.find('.dropdown-toggle-text'); @@ -34,7 +62,7 @@ export default class LabelsSelect { labelUrl = $dropdown.data('labels'); issueUpdateURL = $dropdown.data('issueUpdate'); selectedLabel = $dropdown.data('selected'); - if ((selectedLabel != null) && !$dropdown.hasClass('js-multiselect')) { + if (selectedLabel != null && !$dropdown.hasClass('js-multiselect')) { selectedLabel = selectedLabel.split(','); } showNo = $dropdown.data('showNo'); @@ -50,26 +78,37 @@ export default class LabelsSelect { $value = $block.find('.value'); $loading = $block.find('.block-loading').fadeOut(); fieldName = $dropdown.data('fieldName'); - useId = $dropdown.is('.js-issuable-form-dropdown, .js-filter-bulk-update, .js-label-sidebar-dropdown'); + useId = $dropdown.is( + '.js-issuable-form-dropdown, .js-filter-bulk-update, .js-label-sidebar-dropdown', + ); propertyName = useId ? 'id' : 'title'; initialSelected = $selectbox .find('input[name="' + $dropdown.data('fieldName') + '"]') - .map(function () { + .map(function() { return this.value; - }).get(); + }) + .get(); const { handleClick } = options; $sidebarLabelTooltip.tooltip(); if ($dropdown.closest('.dropdown').find('.dropdown-new-label').length) { - new CreateLabelDropdown($dropdown.closest('.dropdown').find('.dropdown-new-label'), namespacePath, projectPath); + new CreateLabelDropdown( + $dropdown.closest('.dropdown').find('.dropdown-new-label'), + namespacePath, + projectPath, + ); } saveLabelData = function() { var data, selected; - selected = $dropdown.closest('.selectbox').find("input[name='" + fieldName + "']").map(function() { - return this.value; - }).get(); + selected = $dropdown + .closest('.selectbox') + .find("input[name='" + fieldName + "']") + .map(function() { + return this.value; + }) + .get(); if (_.isEqual(initialSelected, selected)) return; initialSelected = selected; @@ -82,7 +121,8 @@ export default class LabelsSelect { } $loading.removeClass('hidden').fadeIn(); $dropdown.trigger('loading.gl.dropdown'); - axios.put(issueUpdateURL, data) + axios + .put(issueUpdateURL, data) .then(({ data }) => { var labelCount, template, labelTooltipTitle, labelTitles, formattedLabels; $loading.fadeOut(); @@ -96,8 +136,7 @@ export default class LabelsSelect { issueUpdateURL, }); labelCount = data.labels.length; - } - else { + } else { template = '<span class="no-value">None</span>'; } $value.removeAttr('style').html(template); @@ -114,17 +153,14 @@ export default class LabelsSelect { } labelTooltipTitle = labelTitles.join(', '); - } - else { + } else { labelTooltipTitle = __('Labels'); } - $sidebarLabelTooltip - .attr('title', labelTooltipTitle) - .tooltip('_fixTitle'); + $sidebarLabelTooltip.attr('title', labelTooltipTitle).tooltip('_fixTitle'); $('.has-tooltip', $value).tooltip({ - container: 'body' + container: 'body', }); }) .catch(() => flash(__('Error saving label update.'))); @@ -132,34 +168,38 @@ export default class LabelsSelect { $dropdown.glDropdown({ showMenuAbove: showMenuAbove, data: function(term, callback) { - axios.get(labelUrl) - .then((res) => { - let data = _.chain(res.data).groupBy(function(label) { - return label.title; - }).map(function(label) { - var color; - color = _.map(label, function(dup) { - return dup.color; - }); - return { - id: label[0].id, - title: label[0].title, - color: color, - duplicate: color.length > 1 - }; - }).value(); + axios + .get(labelUrl) + .then(res => { + let data = _.chain(res.data) + .groupBy(function(label) { + return label.title; + }) + .map(function(label) { + var color; + color = _.map(label, function(dup) { + return dup.color; + }); + return { + id: label[0].id, + title: label[0].title, + color: color, + duplicate: color.length > 1, + }; + }) + .value(); if ($dropdown.hasClass('js-extra-options')) { var extraData = []; if (showNo) { extraData.unshift({ id: 0, - title: 'No Label' + title: 'No Label', }); } if (showAny) { extraData.unshift({ isAny: true, - title: 'Any Label' + title: 'Any Label', }); } if (extraData.length) { @@ -176,11 +216,22 @@ export default class LabelsSelect { .catch(() => flash(__('Error fetching labels.'))); }, renderRow: function(label, instance) { - var $a, $li, color, colorEl, indeterminate, removesAll, selectedClass, spacing, i, marked, dropdownName, dropdownValue; + var $a, + $li, + color, + colorEl, + indeterminate, + removesAll, + selectedClass, + spacing, + i, + marked, + dropdownName, + dropdownValue; $li = $('<li>'); $a = $('<a href="#">'); selectedClass = []; - removesAll = label.id <= 0 || (label.id == null); + removesAll = label.id <= 0 || label.id == null; if ($dropdown.hasClass('js-filter-bulk-update')) { indeterminate = $dropdown.data('indeterminate') || []; marked = $dropdown.data('marked') || []; @@ -200,9 +251,19 @@ export default class LabelsSelect { } else { if (this.id(label)) { dropdownName = $dropdown.data('fieldName'); - dropdownValue = this.id(label).toString().replace(/'/g, '\\\''); - - if ($form.find("input[type='hidden'][name='" + dropdownName + "'][value='" + dropdownValue + "']").length) { + dropdownValue = this.id(label) + .toString() + .replace(/'/g, "\\'"); + + if ( + $form.find( + "input[type='hidden'][name='" + + dropdownName + + "'][value='" + + dropdownValue + + "']", + ).length + ) { selectedClass.push('is-active'); } } @@ -213,16 +274,14 @@ export default class LabelsSelect { } if (label.duplicate) { color = DropdownUtils.duplicateLabelColor(label.color); - } - else { + } else { if (label.color != null) { [color] = label.color; } } if (color) { colorEl = "<span class='dropdown-label-box' style='background: " + color + "'></span>"; - } - else { + } else { colorEl = ''; } // We need to identify which items are actually labels @@ -235,7 +294,7 @@ export default class LabelsSelect { return $li.html($a).prop('outerHTML'); }, search: { - fields: ['title'] + fields: ['title'], }, selectable: true, filterable: true, @@ -255,25 +314,21 @@ export default class LabelsSelect { if (selected && selected.id === 0) { this.selected = []; return 'No Label'; - } - else if (isSelected) { + } else if (isSelected) { this.selected.push(title); - } - else if (!isSelected && title) { + } else if (!isSelected && title) { var index = this.selected.indexOf(title); this.selected.splice(index, 1); } if (selectedLabels.length === 1) { return selectedLabels; - } - else if (selectedLabels.length) { + } else if (selectedLabels.length) { return sprintf(__('%{firstLabel} +%{labelCount} more'), { firstLabel: selectedLabels[0], - labelCount: selectedLabels.length - 1 + labelCount: selectedLabels.length - 1, }); - } - else { + } else { return defaultLabel; } }, @@ -285,10 +340,9 @@ export default class LabelsSelect { return label.id; } - if ($dropdown.hasClass("js-filter-submit") && (label.isAny == null)) { + if ($dropdown.hasClass('js-filter-submit') && label.isAny == null) { return label.title; - } - else { + } else { return label.id; } }, @@ -310,13 +364,13 @@ export default class LabelsSelect { } if ($dropdown.hasClass('js-multiselect')) { if ($dropdown.hasClass('js-filter-submit') && (isIssueIndex || isMRIndex)) { - selectedLabels = $dropdown.closest('form').find("input:hidden[name='" + ($dropdown.data('fieldName')) + "']"); + selectedLabels = $dropdown + .closest('form') + .find("input:hidden[name='" + $dropdown.data('fieldName') + "']"); Issuable.filterResults($dropdown.closest('form')); - } - else if ($dropdown.hasClass('js-filter-submit')) { + } else if ($dropdown.hasClass('js-filter-submit')) { $dropdown.closest('form').submit(); - } - else { + } else { if (!$dropdown.hasClass('js-filter-bulk-update')) { saveLabelData(); } @@ -325,7 +379,7 @@ export default class LabelsSelect { }, multiSelect: $dropdown.hasClass('js-multiselect'), vue: $dropdown.hasClass('js-issue-board-sidebar'), - clicked: function (clickEvent) { + clicked: function(clickEvent) { const { $el, e, isMarking } = clickEvent; const label = clickEvent.selectedObj; @@ -339,7 +393,8 @@ export default class LabelsSelect { isMRIndex = page === 'projects:merge_requests:index'; if ($dropdown.parent().find('.is-active:not(.dropdown-clear-active)').length) { - $dropdown.parent() + $dropdown + .parent() .find('.dropdown-clear-active') .removeClass('is-active'); } @@ -367,28 +422,26 @@ export default class LabelsSelect { e.preventDefault(); return; - } - else if ($dropdown.hasClass('js-filter-submit') && (isIssueIndex || isMRIndex)) { + } else if ($dropdown.hasClass('js-filter-submit') && (isIssueIndex || isMRIndex)) { if (!$dropdown.hasClass('js-multiselect')) { selectedLabel = label.title; return Issuable.filterResults($dropdown.closest('form')); } - } - else if ($dropdown.hasClass('js-filter-submit')) { + } else if ($dropdown.hasClass('js-filter-submit')) { return $dropdown.closest('form').submit(); - } - else if ($dropdown.hasClass('js-issue-board-sidebar')) { + } else if ($dropdown.hasClass('js-issue-board-sidebar')) { if ($el.hasClass('is-active')) { - boardsStore.detail.issue.labels.push(new ListLabel({ - id: label.id, - title: label.title, - color: label.color[0], - textColor: '#fff' - })); - } - else { + boardsStore.detail.issue.labels.push( + new ListLabel({ + id: label.id, + title: label.title, + color: label.color[0], + textColor: '#fff', + }), + ); + } else { var { labels } = boardsStore.detail.issue; - labels = labels.filter(function (selectedLabel) { + labels = labels.filter(function(selectedLabel) { return selectedLabel.id !== label.id; }); boardsStore.detail.issue.labels = labels; @@ -396,19 +449,16 @@ export default class LabelsSelect { $loading.fadeIn(); - boardsStore.detail.issue.update($dropdown.attr('data-issue-update')) + boardsStore.detail.issue + .update($dropdown.attr('data-issue-update')) .then(fadeOutLoader) .catch(fadeOutLoader); - } - else if (handleClick) { + } else if (handleClick) { e.preventDefault(); handleClick(label); - } - else { + } else { if ($dropdown.hasClass('js-multiselect')) { - - } - else { + } else { return saveLabelData(); } } @@ -436,15 +486,17 @@ export default class LabelsSelect { // so best approach is to use traditional way of // concatenation // see: http://2ality.com/2016/05/template-literal-whitespace.html#joining-arrays - const tpl = _.template([ - '<% _.each(labels, function(label){ %>', - '<a href="<%- issueUpdateURL.slice(0, issueUpdateURL.lastIndexOf("/")) %>?label_name[]=<%- encodeURIComponent(label.title) %>">', - '<span class="badge label has-tooltip color-label" title="<%- label.description %>" style="background-color: <%- label.color %>; color: <%- label.text_color %>;">', - '<%- label.title %>', - '</span>', - '</a>', - '<% }); %>', - ].join('')); + const tpl = _.template( + [ + '<% _.each(labels, function(label){ %>', + '<a href="<%- issueUpdateURL.slice(0, issueUpdateURL.lastIndexOf("/")) %>?label_name[]=<%- encodeURIComponent(label.title) %>">', + '<span class="badge label has-tooltip color-label" title="<%- label.description %>" style="background-color: <%- label.color %>; color: <%- label.text_color %>;">', + '<%- label.title %>', + '</span>', + '</a>', + '<% }); %>', + ].join(''), + ); return tpl(tplData); } diff --git a/app/assets/javascripts/lib/utils/ace_utils.js b/app/assets/javascripts/lib/utils/ace_utils.js index efc4b2a8d94..ee71ae0e61a 100644 --- a/app/assets/javascripts/lib/utils/ace_utils.js +++ b/app/assets/javascripts/lib/utils/ace_utils.js @@ -1,6 +1,6 @@ /* global ace */ export default function getModeByFileExtension(path) { - const modelist = ace.require("ace/ext/modelist"); + const modelist = ace.require('ace/ext/modelist'); return modelist.getModeForPath(path).mode; -}; +} diff --git a/app/assets/javascripts/lib/utils/number_utils.js b/app/assets/javascripts/lib/utils/number_utils.js index afbab59055b..2ccc51c35f7 100644 --- a/app/assets/javascripts/lib/utils/number_utils.js +++ b/app/assets/javascripts/lib/utils/number_utils.js @@ -7,7 +7,7 @@ import { BYTES_IN_KIB } from './constants'; * * * Show 3 digits to the right * * For 2 digits to the left of the decimal point and X digits to the right of it * * * Show 2 digits to the right -*/ + */ export function formatRelevantDigits(number) { let digitsLeft = ''; let relevantDigits = 0; diff --git a/app/assets/javascripts/members.js b/app/assets/javascripts/members.js index 7d0c701fd70..bd263c75a3d 100644 --- a/app/assets/javascripts/members.js +++ b/app/assets/javascripts/members.js @@ -7,8 +7,12 @@ export default class Members { } addListeners() { - $('.js-member-update-control').off('change').on('change', this.formSubmit.bind(this)); - $('.js-edit-member-form').off('ajax:success').on('ajax:success', this.formSuccess.bind(this)); + $('.js-member-update-control') + .off('change') + .on('change', this.formSubmit.bind(this)); + $('.js-edit-member-form') + .off('ajax:success') + .on('ajax:success', this.formSuccess.bind(this)); gl.utils.disableButtonIfEmptyField('#user_ids', 'input[name=commit]', 'change'); } @@ -28,7 +32,7 @@ export default class Members { toggleLabel(selected, $el) { return $el.text(); }, - clicked: (options) => { + clicked: options => { this.formSubmit(null, options.$el); }, }); diff --git a/app/assets/javascripts/milestone_select.js b/app/assets/javascripts/milestone_select.js index 42fb5c7177a..d32f39881dd 100644 --- a/app/assets/javascripts/milestone_select.js +++ b/app/assets/javascripts/milestone_select.js @@ -9,7 +9,10 @@ import '~/gl_dropdown'; import axios from './lib/utils/axios_utils'; import { timeFor } from './lib/utils/datetime_utility'; import ModalStore from './boards/stores/modal_store'; -import boardsStore, { boardStoreIssueSet, boardStoreIssueDelete } from './boards/stores/boards_store'; +import boardsStore, { + boardStoreIssueSet, + boardStoreIssueDelete, +} from './boards/stores/boards_store'; export default class MilestoneSelect { constructor(currentProject, els, options = {}) { diff --git a/app/assets/javascripts/notes/components/notes_app.vue b/app/assets/javascripts/notes/components/notes_app.vue index b0faa443a18..7514ce8a1eb 100644 --- a/app/assets/javascripts/notes/components/notes_app.vue +++ b/app/assets/javascripts/notes/components/notes_app.vue @@ -54,7 +54,13 @@ export default { }; }, computed: { - ...mapGetters(['isNotesFetched', 'discussions', 'getNotesDataByProp', 'discussionCount', 'isLoading']), + ...mapGetters([ + 'isNotesFetched', + 'discussions', + 'getNotesDataByProp', + 'discussionCount', + 'isLoading', + ]), noteableType() { return this.noteableData.noteableType; }, diff --git a/app/assets/javascripts/notes/discussion_filters.js b/app/assets/javascripts/notes/discussion_filters.js index 012ffc4093e..06eadaeea0e 100644 --- a/app/assets/javascripts/notes/discussion_filters.js +++ b/app/assets/javascripts/notes/discussion_filters.js @@ -1,15 +1,17 @@ import Vue from 'vue'; import DiscussionFilter from './components/discussion_filter.vue'; -export default (store) => { +export default store => { const discussionFilterEl = document.getElementById('js-vue-discussion-filter'); if (discussionFilterEl) { const { defaultFilter, notesFilters } = discussionFilterEl.dataset; const defaultValue = defaultFilter ? parseInt(defaultFilter, 10) : null; const filterValues = notesFilters ? JSON.parse(notesFilters) : {}; - const filters = Object.keys(filterValues).map(entry => - ({ title: entry, value: filterValues[entry] })); + const filters = Object.keys(filterValues).map(entry => ({ + title: entry, + value: filterValues[entry], + })); return new Vue({ el: discussionFilterEl, diff --git a/app/assets/javascripts/pages/milestones/shared/components/promote_milestone_modal.vue b/app/assets/javascripts/pages/milestones/shared/components/promote_milestone_modal.vue index 2c683a39f42..9d19e4a095d 100644 --- a/app/assets/javascripts/pages/milestones/shared/components/promote_milestone_modal.vue +++ b/app/assets/javascripts/pages/milestones/shared/components/promote_milestone_modal.vue @@ -1,54 +1,66 @@ <script> - import axios from '~/lib/utils/axios_utils'; - import createFlash from '~/flash'; - import GlModal from '~/vue_shared/components/gl_modal.vue'; - import { s__, sprintf } from '~/locale'; - import { visitUrl } from '~/lib/utils/url_utility'; - import eventHub from '../event_hub'; +import axios from '~/lib/utils/axios_utils'; +import createFlash from '~/flash'; +import GlModal from '~/vue_shared/components/gl_modal.vue'; +import { s__, sprintf } from '~/locale'; +import { visitUrl } from '~/lib/utils/url_utility'; +import eventHub from '../event_hub'; - export default { - components: { - GlModal, +export default { + components: { + GlModal, + }, + props: { + milestoneTitle: { + type: String, + required: true, }, - props: { - milestoneTitle: { - type: String, - required: true, - }, - url: { - type: String, - required: true, - }, - groupName: { - type: String, - required: true, - }, + url: { + type: String, + required: true, }, - computed: { - title() { - return sprintf(s__('Milestones|Promote %{milestoneTitle} to group milestone?'), { milestoneTitle: this.milestoneTitle }); - }, - text() { - return sprintf(s__(`Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. + groupName: { + type: String, + required: true, + }, + }, + computed: { + title() { + return sprintf(s__('Milestones|Promote %{milestoneTitle} to group milestone?'), { + milestoneTitle: this.milestoneTitle, + }); + }, + text() { + return sprintf( + s__(`Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged. - This action cannot be reversed.`), { milestoneTitle: this.milestoneTitle, groupName: this.groupName }); - }, + This action cannot be reversed.`), + { milestoneTitle: this.milestoneTitle, groupName: this.groupName }, + ); }, - methods: { - onSubmit() { - eventHub.$emit('promoteMilestoneModal.requestStarted', this.url); - return axios.post(this.url, { params: { format: 'json' } }) - .then((response) => { - eventHub.$emit('promoteMilestoneModal.requestFinished', { milestoneUrl: this.url, successful: true }); - visitUrl(response.data.url); - }) - .catch((error) => { - eventHub.$emit('promoteMilestoneModal.requestFinished', { milestoneUrl: this.url, successful: false }); - createFlash(error); + }, + methods: { + onSubmit() { + eventHub.$emit('promoteMilestoneModal.requestStarted', this.url); + return axios + .post(this.url, { params: { format: 'json' } }) + .then(response => { + eventHub.$emit('promoteMilestoneModal.requestFinished', { + milestoneUrl: this.url, + successful: true, }); - }, + visitUrl(response.data.url); + }) + .catch(error => { + eventHub.$emit('promoteMilestoneModal.requestFinished', { + milestoneUrl: this.url, + successful: false, + }); + createFlash(error); + }); }, - }; + }, +}; </script> <template> <gl-modal @@ -65,4 +77,3 @@ {{ text }} </gl-modal> </template> - diff --git a/app/assets/javascripts/pages/projects/project.js b/app/assets/javascripts/pages/projects/project.js index 52d66beefc9..a6bee49a6b1 100644 --- a/app/assets/javascripts/pages/projects/project.js +++ b/app/assets/javascripts/pages/projects/project.js @@ -64,7 +64,9 @@ export default class Project { const projectId = $(this).data('project-id'); const cookieKey = `hide_auto_devops_implicitly_enabled_banner_${projectId}`; Cookies.set(cookieKey, 'false'); - $(this).parents('.auto-devops-implicitly-enabled-banner').remove(); + $(this) + .parents('.auto-devops-implicitly-enabled-banner') + .remove(); return e.preventDefault(); }); Project.projectSelectDropdown(); diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue index a16f7e6b77c..c0ec7a5dc94 100644 --- a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue +++ b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue @@ -1,202 +1,200 @@ <script> - import projectFeatureSetting from './project_feature_setting.vue'; - import projectFeatureToggle from '../../../../../vue_shared/components/toggle_button.vue'; - import projectSettingRow from './project_setting_row.vue'; - import { visibilityOptions, visibilityLevelDescriptions } from '../constants'; - import { toggleHiddenClassBySelector } from '../external'; +import projectFeatureSetting from './project_feature_setting.vue'; +import projectFeatureToggle from '../../../../../vue_shared/components/toggle_button.vue'; +import projectSettingRow from './project_setting_row.vue'; +import { visibilityOptions, visibilityLevelDescriptions } from '../constants'; +import { toggleHiddenClassBySelector } from '../external'; - export default { - components: { - projectFeatureSetting, - projectFeatureToggle, - projectSettingRow, - }, +export default { + components: { + projectFeatureSetting, + projectFeatureToggle, + projectSettingRow, + }, - props: { - currentSettings: { - type: Object, - required: true, - }, - canChangeVisibilityLevel: { - type: Boolean, - required: false, - default: false, - }, - allowedVisibilityOptions: { - type: Array, - required: false, - default: () => [0, 10, 20], - }, - lfsAvailable: { - type: Boolean, - required: false, - default: false, - }, - registryAvailable: { - type: Boolean, - required: false, - default: false, - }, - visibilityHelpPath: { - type: String, - required: false, - default: '', - }, - lfsHelpPath: { - type: String, - required: false, - default: '', - }, - registryHelpPath: { - type: String, - required: false, - default: '', - }, - pagesAvailable: { - type: Boolean, - required: false, - default: false, - }, - pagesAccessControlEnabled: { - type: Boolean, - required: false, - default: false, - }, - pagesHelpPath: { - type: String, - required: false, - default: '', - }, + props: { + currentSettings: { + type: Object, + required: true, + }, + canChangeVisibilityLevel: { + type: Boolean, + required: false, + default: false, + }, + allowedVisibilityOptions: { + type: Array, + required: false, + default: () => [0, 10, 20], + }, + lfsAvailable: { + type: Boolean, + required: false, + default: false, + }, + registryAvailable: { + type: Boolean, + required: false, + default: false, + }, + visibilityHelpPath: { + type: String, + required: false, + default: '', }, + lfsHelpPath: { + type: String, + required: false, + default: '', + }, + registryHelpPath: { + type: String, + required: false, + default: '', + }, + pagesAvailable: { + type: Boolean, + required: false, + default: false, + }, + pagesAccessControlEnabled: { + type: Boolean, + required: false, + default: false, + }, + pagesHelpPath: { + type: String, + required: false, + default: '', + }, + }, - data() { - const defaults = { - visibilityOptions, - visibilityLevel: visibilityOptions.PUBLIC, - issuesAccessLevel: 20, - repositoryAccessLevel: 20, - mergeRequestsAccessLevel: 20, - buildsAccessLevel: 20, - wikiAccessLevel: 20, - snippetsAccessLevel: 20, - pagesAccessLevel: 20, - containerRegistryEnabled: true, - lfsEnabled: true, - requestAccessEnabled: true, - highlightChangesClass: false, - }; + data() { + const defaults = { + visibilityOptions, + visibilityLevel: visibilityOptions.PUBLIC, + issuesAccessLevel: 20, + repositoryAccessLevel: 20, + mergeRequestsAccessLevel: 20, + buildsAccessLevel: 20, + wikiAccessLevel: 20, + snippetsAccessLevel: 20, + pagesAccessLevel: 20, + containerRegistryEnabled: true, + lfsEnabled: true, + requestAccessEnabled: true, + highlightChangesClass: false, + }; - return { ...defaults, ...this.currentSettings }; - }, + return { ...defaults, ...this.currentSettings }; + }, - computed: { - featureAccessLevelOptions() { - const options = [ - [10, 'Only Project Members'], - ]; - if (this.visibilityLevel !== visibilityOptions.PRIVATE) { - options.push([20, 'Everyone With Access']); - } - return options; - }, + computed: { + featureAccessLevelOptions() { + const options = [[10, 'Only Project Members']]; + if (this.visibilityLevel !== visibilityOptions.PRIVATE) { + options.push([20, 'Everyone With Access']); + } + return options; + }, - repoFeatureAccessLevelOptions() { - return this.featureAccessLevelOptions.filter( - ([value]) => value <= this.repositoryAccessLevel, - ); - }, + repoFeatureAccessLevelOptions() { + return this.featureAccessLevelOptions.filter( + ([value]) => value <= this.repositoryAccessLevel, + ); + }, - pagesFeatureAccessLevelOptions() { - if (this.visibilityLevel !== visibilityOptions.PUBLIC) { - return this.featureAccessLevelOptions.concat([[30, 'Everyone']]); - } - return this.featureAccessLevelOptions; - }, + pagesFeatureAccessLevelOptions() { + if (this.visibilityLevel !== visibilityOptions.PUBLIC) { + return this.featureAccessLevelOptions.concat([[30, 'Everyone']]); + } + return this.featureAccessLevelOptions; + }, - repositoryEnabled() { - return this.repositoryAccessLevel > 0; - }, + repositoryEnabled() { + return this.repositoryAccessLevel > 0; + }, - visibilityLevelDescription() { - return visibilityLevelDescriptions[this.visibilityLevel]; - }, + visibilityLevelDescription() { + return visibilityLevelDescriptions[this.visibilityLevel]; }, + }, - watch: { - visibilityLevel(value, oldValue) { - if (value === visibilityOptions.PRIVATE) { - // when private, features are restricted to "only team members" - this.issuesAccessLevel = Math.min(10, this.issuesAccessLevel); - this.repositoryAccessLevel = Math.min(10, this.repositoryAccessLevel); - this.mergeRequestsAccessLevel = Math.min(10, this.mergeRequestsAccessLevel); - this.buildsAccessLevel = Math.min(10, this.buildsAccessLevel); - this.wikiAccessLevel = Math.min(10, this.wikiAccessLevel); - this.snippetsAccessLevel = Math.min(10, this.snippetsAccessLevel); - if (this.pagesAccessLevel === 20) { - // When from Internal->Private narrow access for only members - this.pagesAccessLevel = 10; - } - this.highlightChanges(); - } else if (oldValue === visibilityOptions.PRIVATE) { - // if changing away from private, make enabled features more permissive - if (this.issuesAccessLevel > 0) this.issuesAccessLevel = 20; - if (this.repositoryAccessLevel > 0) this.repositoryAccessLevel = 20; - if (this.mergeRequestsAccessLevel > 0) this.mergeRequestsAccessLevel = 20; - if (this.buildsAccessLevel > 0) this.buildsAccessLevel = 20; - if (this.wikiAccessLevel > 0) this.wikiAccessLevel = 20; - if (this.snippetsAccessLevel > 0) this.snippetsAccessLevel = 20; - if (this.pagesAccessLevel === 10) this.pagesAccessLevel = 20; - this.highlightChanges(); + watch: { + visibilityLevel(value, oldValue) { + if (value === visibilityOptions.PRIVATE) { + // when private, features are restricted to "only team members" + this.issuesAccessLevel = Math.min(10, this.issuesAccessLevel); + this.repositoryAccessLevel = Math.min(10, this.repositoryAccessLevel); + this.mergeRequestsAccessLevel = Math.min(10, this.mergeRequestsAccessLevel); + this.buildsAccessLevel = Math.min(10, this.buildsAccessLevel); + this.wikiAccessLevel = Math.min(10, this.wikiAccessLevel); + this.snippetsAccessLevel = Math.min(10, this.snippetsAccessLevel); + if (this.pagesAccessLevel === 20) { + // When from Internal->Private narrow access for only members + this.pagesAccessLevel = 10; } - }, + this.highlightChanges(); + } else if (oldValue === visibilityOptions.PRIVATE) { + // if changing away from private, make enabled features more permissive + if (this.issuesAccessLevel > 0) this.issuesAccessLevel = 20; + if (this.repositoryAccessLevel > 0) this.repositoryAccessLevel = 20; + if (this.mergeRequestsAccessLevel > 0) this.mergeRequestsAccessLevel = 20; + if (this.buildsAccessLevel > 0) this.buildsAccessLevel = 20; + if (this.wikiAccessLevel > 0) this.wikiAccessLevel = 20; + if (this.snippetsAccessLevel > 0) this.snippetsAccessLevel = 20; + if (this.pagesAccessLevel === 10) this.pagesAccessLevel = 20; + this.highlightChanges(); + } + }, - repositoryAccessLevel(value, oldValue) { - if (value < oldValue) { - // sub-features cannot have more premissive access level - this.mergeRequestsAccessLevel = Math.min(this.mergeRequestsAccessLevel, value); - this.buildsAccessLevel = Math.min(this.buildsAccessLevel, value); + repositoryAccessLevel(value, oldValue) { + if (value < oldValue) { + // sub-features cannot have more premissive access level + this.mergeRequestsAccessLevel = Math.min(this.mergeRequestsAccessLevel, value); + this.buildsAccessLevel = Math.min(this.buildsAccessLevel, value); - if (value === 0) { - this.containerRegistryEnabled = false; - this.lfsEnabled = false; - } - } else if (oldValue === 0) { - this.mergeRequestsAccessLevel = value; - this.buildsAccessLevel = value; - this.containerRegistryEnabled = true; - this.lfsEnabled = true; + if (value === 0) { + this.containerRegistryEnabled = false; + this.lfsEnabled = false; } - }, + } else if (oldValue === 0) { + this.mergeRequestsAccessLevel = value; + this.buildsAccessLevel = value; + this.containerRegistryEnabled = true; + this.lfsEnabled = true; + } + }, - issuesAccessLevel(value, oldValue) { - if (value === 0) toggleHiddenClassBySelector('.issues-feature', true); - else if (oldValue === 0) toggleHiddenClassBySelector('.issues-feature', false); - }, + issuesAccessLevel(value, oldValue) { + if (value === 0) toggleHiddenClassBySelector('.issues-feature', true); + else if (oldValue === 0) toggleHiddenClassBySelector('.issues-feature', false); + }, - mergeRequestsAccessLevel(value, oldValue) { - if (value === 0) toggleHiddenClassBySelector('.merge-requests-feature', true); - else if (oldValue === 0) toggleHiddenClassBySelector('.merge-requests-feature', false); - }, + mergeRequestsAccessLevel(value, oldValue) { + if (value === 0) toggleHiddenClassBySelector('.merge-requests-feature', true); + else if (oldValue === 0) toggleHiddenClassBySelector('.merge-requests-feature', false); + }, - buildsAccessLevel(value, oldValue) { - if (value === 0) toggleHiddenClassBySelector('.builds-feature', true); - else if (oldValue === 0) toggleHiddenClassBySelector('.builds-feature', false); - }, + buildsAccessLevel(value, oldValue) { + if (value === 0) toggleHiddenClassBySelector('.builds-feature', true); + else if (oldValue === 0) toggleHiddenClassBySelector('.builds-feature', false); }, + }, - methods: { - highlightChanges() { - this.highlightChangesClass = true; - this.$nextTick(() => { - this.highlightChangesClass = false; - }); - }, + methods: { + highlightChanges() { + this.highlightChangesClass = true; + this.$nextTick(() => { + this.highlightChangesClass = false; + }); + }, - visibilityAllowed(option) { - return this.allowedVisibilityOptions.includes(option); - }, + visibilityAllowed(option) { + return this.allowedVisibilityOptions.includes(option); }, - }; + }, +}; </script> <template> diff --git a/app/assets/javascripts/projects/project_new.js b/app/assets/javascripts/projects/project_new.js index ebe18b47e4e..998554d1be5 100644 --- a/app/assets/javascripts/projects/project_new.js +++ b/app/assets/javascripts/projects/project_new.js @@ -4,8 +4,10 @@ import { slugifyWithHyphens } from '../lib/utils/text_utility'; let hasUserDefinedProjectPath = false; -const deriveProjectPathFromUrl = ($projectImportUrl) => { - const $currentProjectPath = $projectImportUrl.parents('.toggle-import-form').find('#project_path'); +const deriveProjectPathFromUrl = $projectImportUrl => { + const $currentProjectPath = $projectImportUrl + .parents('.toggle-import-form') + .find('#project_path'); if (hasUserDefinedProjectPath) { return; } @@ -52,9 +54,11 @@ const bindEvents = () => { return; } - $('.how_to_import_link').on('click', (e) => { + $('.how_to_import_link').on('click', e => { e.preventDefault(); - $(e.currentTarget).next('.modal').show(); + $(e.currentTarget) + .next('.modal') + .show(); }); $('.modal-header .close').on('click', () => { @@ -63,15 +67,21 @@ const bindEvents = () => { $('.btn_import_gitlab_project').on('click', () => { const importHref = $('a.btn_import_gitlab_project').attr('href'); - $('.btn_import_gitlab_project') - .attr('href', `${importHref}?namespace_id=${$('#project_namespace_id').val()}&name=${$projectName.val()}&path=${$projectPath.val()}`); + $('.btn_import_gitlab_project').attr( + 'href', + `${importHref}?namespace_id=${$( + '#project_namespace_id', + ).val()}&name=${$projectName.val()}&path=${$projectPath.val()}`, + ); }); if ($pushNewProjectTipTrigger) { $pushNewProjectTipTrigger .removeAttr('rel') .removeAttr('target') - .on('click', (e) => { e.preventDefault(); }) + .on('click', e => { + e.preventDefault(); + }) .popover({ title: $pushNewProjectTipTrigger.data('title'), placement: 'bottom', @@ -79,13 +89,15 @@ const bindEvents = () => { content: $('.push-new-project-tip-template').html(), }) .on('shown.bs.popover', () => { - $(document).on('click.popover touchstart.popover', (event) => { + $(document).on('click.popover touchstart.popover', event => { if ($(event.target).closest('.popover').length === 0) { $pushNewProjectTipTrigger.trigger('click'); } }); - const target = $(`#${$pushNewProjectTipTrigger.attr('aria-describedby')}`).find('.js-select-on-focus'); + const target = $(`#${$pushNewProjectTipTrigger.attr('aria-describedby')}`).find( + '.js-select-on-focus', + ); addSelectOnFocusBehaviour(target); target.focus(); @@ -117,16 +129,18 @@ const bindEvents = () => { const selectedTemplate = templates[value]; $selectedTemplateText.text(selectedTemplate.text); - $(selectedTemplate.icon).clone().addClass('d-block').appendTo($selectedIcon); + $(selectedTemplate.icon) + .clone() + .addClass('d-block') + .appendTo($selectedIcon); const $activeTabProjectName = $('.tab-pane.active #project_name'); const $activeTabProjectPath = $('.tab-pane.active #project_path'); $activeTabProjectName.focus(); - $activeTabProjectName - .keyup(() => { - onProjectNameChange($activeTabProjectName, $activeTabProjectPath); - hasUserDefinedProjectPath = $activeTabProjectPath.val().trim().length > 0; - }); + $activeTabProjectName.keyup(() => { + onProjectNameChange($activeTabProjectName, $activeTabProjectPath); + hasUserDefinedProjectPath = $activeTabProjectPath.val().trim().length > 0; + }); } $useTemplateBtn.on('change', chooseTemplate); diff --git a/app/assets/javascripts/right_sidebar.js b/app/assets/javascripts/right_sidebar.js index 6b3753f7966..225e21ad322 100644 --- a/app/assets/javascripts/right_sidebar.js +++ b/app/assets/javascripts/right_sidebar.js @@ -21,7 +21,7 @@ Sidebar.initialize = function(currentUser) { } }; -Sidebar.prototype.removeListeners = function () { +Sidebar.prototype.removeListeners = function() { this.sidebar.off('click', '.sidebar-collapsed-icon'); this.sidebar.off('hidden.gl.dropdown'); $('.dropdown').off('loading.gl.dropdown'); @@ -38,10 +38,12 @@ Sidebar.prototype.addEventListeners = function() { $('.dropdown').on('loaded.gl.dropdown', this.sidebarDropdownLoaded); $document.on('click', '.js-sidebar-toggle', this.sidebarToggleClicked); - return $(document).off('click', '.js-issuable-todo').on('click', '.js-issuable-todo', this.toggleTodo); + return $(document) + .off('click', '.js-issuable-todo') + .on('click', '.js-issuable-todo', this.toggleTodo); }; -Sidebar.prototype.sidebarToggleClicked = function (e, triggered) { +Sidebar.prototype.sidebarToggleClicked = function(e, triggered) { var $allGutterToggleIcons, $this, isExpanded, tooltipLabel; e.preventDefault(); $this = $(this); @@ -51,18 +53,26 @@ Sidebar.prototype.sidebarToggleClicked = function (e, triggered) { if (isExpanded) { $allGutterToggleIcons.removeClass('fa-angle-double-right').addClass('fa-angle-double-left'); - $('aside.right-sidebar').removeClass('right-sidebar-expanded').addClass('right-sidebar-collapsed'); - $('.layout-page').removeClass('right-sidebar-expanded').addClass('right-sidebar-collapsed'); + $('aside.right-sidebar') + .removeClass('right-sidebar-expanded') + .addClass('right-sidebar-collapsed'); + $('.layout-page') + .removeClass('right-sidebar-expanded') + .addClass('right-sidebar-collapsed'); } else { $allGutterToggleIcons.removeClass('fa-angle-double-left').addClass('fa-angle-double-right'); - $('aside.right-sidebar').removeClass('right-sidebar-collapsed').addClass('right-sidebar-expanded'); - $('.layout-page').removeClass('right-sidebar-collapsed').addClass('right-sidebar-expanded'); + $('aside.right-sidebar') + .removeClass('right-sidebar-collapsed') + .addClass('right-sidebar-expanded'); + $('.layout-page') + .removeClass('right-sidebar-collapsed') + .addClass('right-sidebar-expanded'); } $this.attr('data-original-title', tooltipLabel); if (!triggered) { - Cookies.set("collapsed_gutter", $('.right-sidebar').hasClass('right-sidebar-collapsed')); + Cookies.set('collapsed_gutter', $('.right-sidebar').hasClass('right-sidebar-collapsed')); } }; @@ -71,21 +81,27 @@ Sidebar.prototype.toggleTodo = function(e) { $this = $(e.currentTarget); ajaxType = $this.attr('data-delete-path') ? 'delete' : 'post'; if ($this.attr('data-delete-path')) { - url = "" + ($this.attr('data-delete-path')); + url = '' + $this.attr('data-delete-path'); } else { - url = "" + ($this.data('url')); + url = '' + $this.data('url'); } $this.tooltip('hide'); - $('.js-issuable-todo').disable().addClass('is-loading'); + $('.js-issuable-todo') + .disable() + .addClass('is-loading'); axios[ajaxType](url, { issuable_id: $this.data('issuableId'), issuable_type: $this.data('issuableType'), - }).then(({ data }) => { - this.todoUpdateDone(data); - }).catch(() => flash(`There was an error ${ajaxType === 'post' ? 'adding a' : 'deleting the'} todo.`)); + }) + .then(({ data }) => { + this.todoUpdateDone(data); + }) + .catch(() => + flash(`There was an error ${ajaxType === 'post' ? 'adding a' : 'deleting the'} todo.`), + ); }; Sidebar.prototype.todoUpdateDone = function(data) { @@ -99,7 +115,8 @@ Sidebar.prototype.todoUpdateDone = function(data) { const $el = $(el); const $elText = $el.find('.js-issuable-todo-inner'); - $el.removeClass('is-loading') + $el + .removeClass('is-loading') .enable() .attr('aria-label', $el.data(`${attrPrefix}Text`)) .attr('data-delete-path', deletePath) @@ -119,7 +136,9 @@ Sidebar.prototype.todoUpdateDone = function(data) { Sidebar.prototype.sidebarDropdownLoading = function(e) { var $loading, $sidebarCollapsedIcon, i, img; - $sidebarCollapsedIcon = $(this).closest('.block').find('.sidebar-collapsed-icon'); + $sidebarCollapsedIcon = $(this) + .closest('.block') + .find('.sidebar-collapsed-icon'); img = $sidebarCollapsedIcon.find('img'); i = $sidebarCollapsedIcon.find('i'); $loading = $('<i class="fa fa-spinner fa-spin"></i>'); @@ -134,7 +153,9 @@ Sidebar.prototype.sidebarDropdownLoading = function(e) { Sidebar.prototype.sidebarDropdownLoaded = function(e) { var $sidebarCollapsedIcon, i, img; - $sidebarCollapsedIcon = $(this).closest('.block').find('.sidebar-collapsed-icon'); + $sidebarCollapsedIcon = $(this) + .closest('.block') + .find('.sidebar-collapsed-icon'); img = $sidebarCollapsedIcon.find('img'); $sidebarCollapsedIcon.find('i.fa-spin').remove(); i = $sidebarCollapsedIcon.find('i'); @@ -220,7 +241,7 @@ Sidebar.prototype.isOpen = function() { }; Sidebar.prototype.getBlock = function(name) { - return this.sidebar.find(".block." + name); + return this.sidebar.find('.block.' + name); }; export default Sidebar; diff --git a/app/assets/javascripts/search_autocomplete.js b/app/assets/javascripts/search_autocomplete.js index ad4f5320ff8..17def77b2d7 100644 --- a/app/assets/javascripts/search_autocomplete.js +++ b/app/assets/javascripts/search_autocomplete.js @@ -234,7 +234,9 @@ export class SearchAutocomplete { icon, text: term, template, - url: `${gon.relative_url_root}/search?search=${term}&project_id=${this.projectInputEl.val()}&group_id=${this.groupInputEl.val()}`, + url: `${ + gon.relative_url_root + }/search?search=${term}&project_id=${this.projectInputEl.val()}&group_id=${this.groupInputEl.val()}`, }); } } diff --git a/app/assets/javascripts/sidebar/components/assignees/assignees.vue b/app/assets/javascripts/sidebar/components/assignees/assignees.vue index dd155c133ce..f1ea6aacdb2 100644 --- a/app/assets/javascripts/sidebar/components/assignees/assignees.vue +++ b/app/assets/javascripts/sidebar/components/assignees/assignees.vue @@ -74,8 +74,8 @@ export default { } if (!this.users.length) { - const emptyTooltipLabel = this.issuableType === 'issue' ? - __('Assignee(s)') : __('Assignee'); + const emptyTooltipLabel = + this.issuableType === 'issue' ? __('Assignee(s)') : __('Assignee'); names.push(emptyTooltipLabel); } @@ -248,4 +248,3 @@ export default { </div> </div> </template> - diff --git a/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue b/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue index 448c8fc3602..b6151aa6c64 100644 --- a/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue +++ b/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue @@ -1,74 +1,74 @@ <script> - import { __ } from '~/locale'; - import icon from '~/vue_shared/components/icon.vue'; - import toggleButton from '~/vue_shared/components/toggle_button.vue'; - import tooltip from '~/vue_shared/directives/tooltip'; - import eventHub from '../../event_hub'; +import { __ } from '~/locale'; +import icon from '~/vue_shared/components/icon.vue'; +import toggleButton from '~/vue_shared/components/toggle_button.vue'; +import tooltip from '~/vue_shared/directives/tooltip'; +import eventHub from '../../event_hub'; - const ICON_ON = 'notifications'; - const ICON_OFF = 'notifications-off'; - const LABEL_ON = __('Notifications on'); - const LABEL_OFF = __('Notifications off'); +const ICON_ON = 'notifications'; +const ICON_OFF = 'notifications-off'; +const LABEL_ON = __('Notifications on'); +const LABEL_OFF = __('Notifications off'); - export default { - directives: { - tooltip, +export default { + directives: { + tooltip, + }, + components: { + icon, + toggleButton, + }, + props: { + loading: { + type: Boolean, + required: false, + default: false, }, - components: { - icon, - toggleButton, + subscribed: { + type: Boolean, + required: false, + default: null, }, - props: { - loading: { - type: Boolean, - required: false, - default: false, - }, - subscribed: { - type: Boolean, - required: false, - default: null, - }, - id: { - type: Number, - required: false, - default: null, - }, + id: { + type: Number, + required: false, + default: null, }, - computed: { - showLoadingState() { - return this.subscribed === null; - }, - notificationIcon() { - return this.subscribed ? ICON_ON : ICON_OFF; - }, - notificationTooltip() { - return this.subscribed ? LABEL_ON : LABEL_OFF; - }, + }, + computed: { + showLoadingState() { + return this.subscribed === null; }, - methods: { - /** - * We need to emit this event on both component & eventHub - * for 2 dependencies; - * - * 1. eventHub: This component is used in Issue Boards sidebar - * where component template is part of HAML - * and event listeners are tied to app's eventHub. - * 2. Component: This compone is also used in Epics in EE - * where listeners are tied to component event. - */ - toggleSubscription() { - // App's eventHub event emission. - eventHub.$emit('toggleSubscription', this.id); + notificationIcon() { + return this.subscribed ? ICON_ON : ICON_OFF; + }, + notificationTooltip() { + return this.subscribed ? LABEL_ON : LABEL_OFF; + }, + }, + methods: { + /** + * We need to emit this event on both component & eventHub + * for 2 dependencies; + * + * 1. eventHub: This component is used in Issue Boards sidebar + * where component template is part of HAML + * and event listeners are tied to app's eventHub. + * 2. Component: This compone is also used in Epics in EE + * where listeners are tied to component event. + */ + toggleSubscription() { + // App's eventHub event emission. + eventHub.$emit('toggleSubscription', this.id); - // Component event emission. - this.$emit('toggleSubscription', this.id); - }, - onClickCollapsedIcon() { - this.$emit('toggleSidebar'); - }, + // Component event emission. + this.$emit('toggleSubscription', this.id); + }, + onClickCollapsedIcon() { + this.$emit('toggleSidebar'); }, - }; + }, +}; </script> <template> diff --git a/app/assets/javascripts/sidebar/sidebar_mediator.js b/app/assets/javascripts/sidebar/sidebar_mediator.js index d9ca5e46770..3e040ec8428 100644 --- a/app/assets/javascripts/sidebar/sidebar_mediator.js +++ b/app/assets/javascripts/sidebar/sidebar_mediator.js @@ -39,9 +39,10 @@ export default class SidebarMediator { } fetch() { - return this.service.get() + return this.service + .get() .then(response => response.json()) - .then((data) => { + .then(data => { this.processFetchedData(data); }) .catch(() => new Flash('Error occurred when fetching sidebar data')); @@ -56,30 +57,33 @@ export default class SidebarMediator { toggleSubscription() { this.store.setFetchingState('subscriptions', true); - return this.service.toggleSubscription() + return this.service + .toggleSubscription() .then(() => { this.store.setSubscribedState(!this.store.subscribed); this.store.setFetchingState('subscriptions', false); }) - .catch((err) => { + .catch(err => { this.store.setFetchingState('subscriptions', false); throw err; }); } fetchAutocompleteProjects(searchTerm) { - return this.service.getProjectsAutocomplete(searchTerm) + return this.service + .getProjectsAutocomplete(searchTerm) .then(response => response.json()) - .then((data) => { + .then(data => { this.store.setAutocompleteProjects(data); return this.store.autocompleteProjects; }); } moveIssue() { - return this.service.moveIssue(this.store.moveToProjectId) + return this.service + .moveIssue(this.store.moveToProjectId) .then(response => response.json()) - .then((data) => { + .then(data => { if (window.location.pathname !== data.web_url) { visitUrl(data.web_url); } diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue index bd1946f337e..8bcabc10225 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue @@ -63,10 +63,15 @@ export default { return this.pipeline.commit && Object.keys(this.pipeline.commit).length > 0; }, errorText() { - return sprintf(__('Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}'), { - linkStart: `<a href="${this.troubleshootingDocsPath}">`, - linkEnd: '</a>', - }); + return sprintf( + __( + 'Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}', + ), + { + linkStart: `<a href="${this.troubleshootingDocsPath}">`, + linkEnd: '</a>', + }, + ); }, }, }; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue index c8ad2aa30a6..e7baecbcde4 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue @@ -71,7 +71,12 @@ export default { return defaultClass; }, iconClass() { - if (this.status === 'failed' || !this.commitMessage.length || !this.mr.isMergeAllowed || this.mr.preventMerge) { + if ( + this.status === 'failed' || + !this.commitMessage.length || + !this.mr.isMergeAllowed || + this.mr.preventMerge + ) { return 'warning'; } return 'success'; @@ -90,10 +95,12 @@ export default { }, isMergeButtonDisabled() { const { commitMessage } = this; - return Boolean(!commitMessage.length - || !this.shouldShowMergeControls() - || this.isMakingRequest - || this.mr.preventMerge); + return Boolean( + !commitMessage.length || + !this.shouldShowMergeControls() || + this.isMakingRequest || + this.mr.preventMerge, + ); }, isRemoveSourceBranchButtonDisabled() { return this.isMergeButtonDisabled; @@ -140,9 +147,10 @@ export default { }; this.isMakingRequest = true; - this.service.merge(options) + this.service + .merge(options) .then(res => res.data) - .then((data) => { + .then(data => { const hasError = data.status === 'failed' || data.status === 'hook_validation_error'; if (data.status === 'merge_when_pipeline_succeeds') { @@ -167,9 +175,10 @@ export default { }); }, handleMergePolling(continuePolling, stopPolling) { - this.service.poll() + this.service + .poll() .then(res => res.data) - .then((data) => { + .then(data => { if (data.state === 'merged') { // If state is merged we should update the widget and stop the polling eventHub.$emit('MRWidgetUpdateRequested'); @@ -205,9 +214,10 @@ export default { }); }, handleRemoveBranchPolling(continuePolling, stopPolling) { - this.service.poll() + this.service + .poll() .then(res => res.data) - .then((data) => { + .then(data => { // If source branch exists then we should continue polling // because removing a source branch is a background task and takes time if (data.source_branch_exists) { diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue index 33064f82ef7..063d1e15544 100644 --- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue +++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue @@ -116,7 +116,7 @@ export default { // init polling this.initPostMergeDeploymentsPolling(); } - } + }, }, created() { this.initPolling(); @@ -213,17 +213,21 @@ export default { }) .catch(() => this.throwDeploymentsError()); }, - fetchPostMergeDeployments(){ + fetchPostMergeDeployments() { return this.fetchDeployments('merge_commit') .then(({ data }) => { if (data.length) { this.mr.postMergeDeployments = data; } }) - .catch(() => this.throwDeploymentsError()); + .catch(() => this.throwDeploymentsError()); }, throwDeploymentsError() { - createFlash(__('Something went wrong while fetching the environments for this merge request. Please try again.')); + createFlash( + __( + 'Something went wrong while fetching the environments for this merge request. Please try again.', + ), + ); }, fetchActionsContent() { this.service diff --git a/app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js b/app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js index bf5b85b2ae6..0bb70bfd658 100644 --- a/app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js +++ b/app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js @@ -24,8 +24,8 @@ export default class MRWidgetService { fetchDeployments(targetParam) { return axios.get(this.endpoints.ciEnvironmentsStatusPath, { params: { - environment_target: targetParam - } + environment_target: targetParam, + }, }); } diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js index c17e9c9e4d6..5c9a7133a6e 100644 --- a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js +++ b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js @@ -18,8 +18,7 @@ export default class MergeRequestStore { this.squash = data.squash; this.squashBeforeMergeHelpPath = this.squashBeforeMergeHelpPath || data.squash_before_merge_help_path; - this.troubleshootingDocsPath = - this.troubleshootingDocsPath || data.troubleshooting_docs_path; + this.troubleshootingDocsPath = this.troubleshootingDocsPath || data.troubleshooting_docs_path; this.enableSquashBeforeMerge = this.enableSquashBeforeMerge || true; this.iid = data.iid; diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_dropdown.vue b/app/assets/javascripts/vue_shared/components/filtered_search_dropdown.vue index 460fa6ad72e..388a2f4ca36 100644 --- a/app/assets/javascripts/vue_shared/components/filtered_search_dropdown.vue +++ b/app/assets/javascripts/vue_shared/components/filtered_search_dropdown.vue @@ -56,12 +56,14 @@ export default { filteredResults() { if (this.filter !== '') { return this.items.filter( - item => item[this.filterKey] && item[this.filterKey].toLowerCase().includes(this.filter.toLowerCase()), + item => + item[this.filterKey] && + item[this.filterKey].toLowerCase().includes(this.filter.toLowerCase()), ); } return this.items.slice(0, this.visibleItems); - } + }, }, mounted() { /** diff --git a/app/assets/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon.vue b/app/assets/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon.vue index 11fac3bb12c..5841db52704 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon.vue @@ -1,39 +1,39 @@ <script> - import tooltip from '~/vue_shared/directives/tooltip'; +import tooltip from '~/vue_shared/directives/tooltip'; - export default { - name: 'CollapsedCalendarIcon', - directives: { - tooltip, +export default { + name: 'CollapsedCalendarIcon', + directives: { + tooltip, + }, + props: { + containerClass: { + type: String, + required: false, + default: '', }, - props: { - containerClass: { - type: String, - required: false, - default: '', - }, - text: { - type: String, - required: false, - default: '', - }, - showIcon: { - type: Boolean, - required: false, - default: true, - }, - tooltipText: { - type: String, - required: false, - default: '', - }, + text: { + type: String, + required: false, + default: '', }, - methods: { - click() { - this.$emit('click'); - }, + showIcon: { + type: Boolean, + required: false, + default: true, }, - }; + tooltipText: { + type: String, + required: false, + default: '', + }, + }, + methods: { + click() { + this.$emit('click'); + }, + }, +}; </script> <template> diff --git a/app/assets/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker.vue b/app/assets/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker.vue index 6e7194ccc9e..174c29809ac 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker.vue @@ -1,84 +1,79 @@ <script> - import { __ } from '~/locale'; - import timeagoMixin from '~/vue_shared/mixins/timeago'; - import { dateInWords, timeFor } from '~/lib/utils/datetime_utility'; - import collapsedCalendarIcon from './collapsed_calendar_icon.vue'; +import { __ } from '~/locale'; +import timeagoMixin from '~/vue_shared/mixins/timeago'; +import { dateInWords, timeFor } from '~/lib/utils/datetime_utility'; +import collapsedCalendarIcon from './collapsed_calendar_icon.vue'; - export default { - name: 'SidebarCollapsedGroupedDatePicker', - components: { - collapsedCalendarIcon, +export default { + name: 'SidebarCollapsedGroupedDatePicker', + components: { + collapsedCalendarIcon, + }, + mixins: [timeagoMixin], + props: { + collapsed: { + type: Boolean, + required: false, + default: true, }, - mixins: [ - timeagoMixin, - ], - props: { - collapsed: { - type: Boolean, - required: false, - default: true, - }, - minDate: { - type: Date, - required: false, - default: null, - }, - maxDate: { - type: Date, - required: false, - default: null, - }, - disableClickableIcons: { - type: Boolean, - required: false, - default: false, - }, + minDate: { + type: Date, + required: false, + default: null, }, - computed: { - hasMinAndMaxDates() { - return this.minDate && this.maxDate; - }, - hasNoMinAndMaxDates() { - return !this.minDate && !this.maxDate; - }, - showMinDateBlock() { - return this.minDate || this.hasNoMinAndMaxDates; - }, - showFromText() { - return !this.maxDate && this.minDate; - }, - iconClass() { - const disabledClass = this.disableClickableIcons ? 'disabled' : ''; - return `sidebar-collapsed-icon calendar-icon ${disabledClass}`; - }, + maxDate: { + type: Date, + required: false, + default: null, }, - methods: { - toggleSidebar() { - this.$emit('toggleCollapse'); - }, - dateText(dateType = 'min') { - const date = this[`${dateType}Date`]; - const dateWords = dateInWords(date, true); - const parsedDateWords = dateWords ? dateWords.replace(',', '') : dateWords; + disableClickableIcons: { + type: Boolean, + required: false, + default: false, + }, + }, + computed: { + hasMinAndMaxDates() { + return this.minDate && this.maxDate; + }, + hasNoMinAndMaxDates() { + return !this.minDate && !this.maxDate; + }, + showMinDateBlock() { + return this.minDate || this.hasNoMinAndMaxDates; + }, + showFromText() { + return !this.maxDate && this.minDate; + }, + iconClass() { + const disabledClass = this.disableClickableIcons ? 'disabled' : ''; + return `sidebar-collapsed-icon calendar-icon ${disabledClass}`; + }, + }, + methods: { + toggleSidebar() { + this.$emit('toggleCollapse'); + }, + dateText(dateType = 'min') { + const date = this[`${dateType}Date`]; + const dateWords = dateInWords(date, true); + const parsedDateWords = dateWords ? dateWords.replace(',', '') : dateWords; - return date ? parsedDateWords : __('None'); - }, - tooltipText(dateType = 'min') { - const defaultText = dateType === 'min' ? __('Start date') : __('Due date'); - const date = this[`${dateType}Date`]; - const timeAgo = dateType === 'min' ? this.timeFormated(date) : timeFor(date); - const dateText = date ? [ - this.dateText(dateType), - `(${timeAgo})`, - ].join(' ') : ''; + return date ? parsedDateWords : __('None'); + }, + tooltipText(dateType = 'min') { + const defaultText = dateType === 'min' ? __('Start date') : __('Due date'); + const date = this[`${dateType}Date`]; + const timeAgo = dateType === 'min' ? this.timeFormated(date) : timeFor(date); + const dateText = date ? [this.dateText(dateType), `(${timeAgo})`].join(' ') : ''; - if (date) { - return [defaultText, dateText].join('<br />'); - } - return __('Start and due date'); - }, + if (date) { + return [defaultText, dateText].join('<br />'); + } + return __('Start and due date'); }, - }; + }, +}; </script> <template> diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed.vue index af297f3c408..0d5fc07e6e3 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed.vue @@ -14,7 +14,10 @@ export default { }, computed: { labelsList() { - const labelsString = this.labels.slice(0, 5).map(label => label.title).join(', '); + const labelsString = this.labels + .slice(0, 5) + .map(label => label.title) + .join(', '); if (this.labels.length > 5) { return sprintf(s__('LabelSelect|%{labelsString}, and %{remainingLabelCount} more'), { diff --git a/spec/javascripts/boards/board_list_spec.js b/spec/javascripts/boards/board_list_spec.js index 037e06cf3b2..2642c8b1bdb 100644 --- a/spec/javascripts/boards/board_list_spec.js +++ b/spec/javascripts/boards/board_list_spec.js @@ -18,7 +18,7 @@ describe('Board list component', () => { let mock; let component; - beforeEach((done) => { + beforeEach(done => { const el = document.createElement('div'); document.body.appendChild(el); @@ -62,122 +62,102 @@ describe('Board list component', () => { }); it('renders component', () => { - expect( - component.$el.classList.contains('board-list-component'), - ).toBe(true); + expect(component.$el.classList.contains('board-list-component')).toBe(true); }); - it('renders loading icon', (done) => { + it('renders loading icon', done => { component.loading = true; Vue.nextTick(() => { - expect( - component.$el.querySelector('.board-list-loading'), - ).not.toBeNull(); + expect(component.$el.querySelector('.board-list-loading')).not.toBeNull(); done(); }); }); it('renders issues', () => { - expect( - component.$el.querySelectorAll('.board-card').length, - ).toBe(1); + expect(component.$el.querySelectorAll('.board-card').length).toBe(1); }); it('sets data attribute with issue id', () => { - expect( - component.$el.querySelector('.board-card').getAttribute('data-issue-id'), - ).toBe('1'); + expect(component.$el.querySelector('.board-card').getAttribute('data-issue-id')).toBe('1'); }); - it('shows new issue form', (done) => { + it('shows new issue form', done => { component.toggleForm(); Vue.nextTick(() => { - expect( - component.$el.querySelector('.board-new-issue-form'), - ).not.toBeNull(); + expect(component.$el.querySelector('.board-new-issue-form')).not.toBeNull(); - expect( - component.$el.querySelector('.is-smaller'), - ).not.toBeNull(); + expect(component.$el.querySelector('.is-smaller')).not.toBeNull(); done(); }); }); - it('shows new issue form after eventhub event', (done) => { + it('shows new issue form after eventhub event', done => { eventHub.$emit(`hide-issue-form-${component.list.id}`); Vue.nextTick(() => { - expect( - component.$el.querySelector('.board-new-issue-form'), - ).not.toBeNull(); + expect(component.$el.querySelector('.board-new-issue-form')).not.toBeNull(); - expect( - component.$el.querySelector('.is-smaller'), - ).not.toBeNull(); + expect(component.$el.querySelector('.is-smaller')).not.toBeNull(); done(); }); }); - it('does not show new issue form for closed list', (done) => { + it('does not show new issue form for closed list', done => { component.list.type = 'closed'; component.toggleForm(); Vue.nextTick(() => { - expect( - component.$el.querySelector('.board-new-issue-form'), - ).toBeNull(); + expect(component.$el.querySelector('.board-new-issue-form')).toBeNull(); done(); }); }); - it('shows count list item', (done) => { + it('shows count list item', done => { component.showCount = true; Vue.nextTick(() => { - expect( - component.$el.querySelector('.board-list-count'), - ).not.toBeNull(); + expect(component.$el.querySelector('.board-list-count')).not.toBeNull(); - expect( - component.$el.querySelector('.board-list-count').textContent.trim(), - ).toBe('Showing all issues'); + expect(component.$el.querySelector('.board-list-count').textContent.trim()).toBe( + 'Showing all issues', + ); done(); }); }); - it('sets data attribute with invalid id', (done) => { + it('sets data attribute with invalid id', done => { component.showCount = true; Vue.nextTick(() => { - expect( - component.$el.querySelector('.board-list-count').getAttribute('data-issue-id'), - ).toBe('-1'); + expect(component.$el.querySelector('.board-list-count').getAttribute('data-issue-id')).toBe( + '-1', + ); done(); }); }); - it('shows how many more issues to load', (done) => { + it('shows how many more issues to load', done => { component.showCount = true; component.list.issuesSize = 20; Vue.nextTick(() => { - expect( - component.$el.querySelector('.board-list-count').textContent.trim(), - ).toBe('Showing 1 of 20 issues'); + expect(component.$el.querySelector('.board-list-count').textContent.trim()).toBe( + 'Showing 1 of 20 issues', + ); done(); }); }); - it('loads more issues after scrolling', (done) => { + it('loads more issues after scrolling', done => { spyOn(component.list, 'nextPage'); component.$refs.list.style.height = '100px'; component.$refs.list.style.overflow = 'scroll'; @@ -200,7 +180,9 @@ describe('Board list component', () => { }); it('does not load issues if already loading', () => { - component.list.nextPage = spyOn(component.list, 'nextPage').and.returnValue(new Promise(() => {})); + component.list.nextPage = spyOn(component.list, 'nextPage').and.returnValue( + new Promise(() => {}), + ); component.onScroll(); component.onScroll(); @@ -208,14 +190,12 @@ describe('Board list component', () => { expect(component.list.nextPage).toHaveBeenCalledTimes(1); }); - it('shows loading more spinner', (done) => { + it('shows loading more spinner', done => { component.showCount = true; component.list.loadingMore = true; Vue.nextTick(() => { - expect( - component.$el.querySelector('.board-list-count .fa-spinner'), - ).not.toBeNull(); + expect(component.$el.querySelector('.board-list-count .fa-spinner')).not.toBeNull(); done(); }); diff --git a/spec/javascripts/boards/components/board_spec.js b/spec/javascripts/boards/components/board_spec.js index d4c53bd5a7d..dee7841c088 100644 --- a/spec/javascripts/boards/components/board_spec.js +++ b/spec/javascripts/boards/components/board_spec.js @@ -8,7 +8,7 @@ describe('Board component', () => { let vm; let el; - beforeEach((done) => { + beforeEach(done => { loadFixtures('boards/show.html.raw'); el = document.createElement('div'); @@ -50,56 +50,46 @@ describe('Board component', () => { }); it('board is expandable when list type is backlog', () => { - expect( - vm.$el.classList.contains('is-expandable'), - ).toBe(true); + expect(vm.$el.classList.contains('is-expandable')).toBe(true); }); - it('board is expandable when list type is closed', (done) => { + it('board is expandable when list type is closed', done => { vm.list.type = 'closed'; Vue.nextTick(() => { - expect( - vm.$el.classList.contains('is-expandable'), - ).toBe(true); + expect(vm.$el.classList.contains('is-expandable')).toBe(true); done(); }); }); - it('board is not expandable when list type is label', (done) => { + it('board is not expandable when list type is label', done => { vm.list.type = 'label'; vm.list.isExpandable = false; Vue.nextTick(() => { - expect( - vm.$el.classList.contains('is-expandable'), - ).toBe(false); + expect(vm.$el.classList.contains('is-expandable')).toBe(false); done(); }); }); - it('collapses when clicking header', (done) => { + it('collapses when clicking header', done => { vm.$el.querySelector('.board-header').click(); Vue.nextTick(() => { - expect( - vm.$el.classList.contains('is-collapsed'), - ).toBe(true); + expect(vm.$el.classList.contains('is-collapsed')).toBe(true); done(); }); }); - it('created sets isExpanded to true from localStorage', (done) => { + it('created sets isExpanded to true from localStorage', done => { vm.$el.querySelector('.board-header').click(); return Vue.nextTick() .then(() => { - expect( - vm.$el.classList.contains('is-collapsed'), - ).toBe(true); + expect(vm.$el.classList.contains('is-collapsed')).toBe(true); // call created manually vm.$options.created[0].call(vm); @@ -107,11 +97,10 @@ describe('Board component', () => { return Vue.nextTick(); }) .then(() => { - expect( - vm.$el.classList.contains('is-collapsed'), - ).toBe(true); + expect(vm.$el.classList.contains('is-collapsed')).toBe(true); done(); - }).catch(done.fail); + }) + .catch(done.fail); }); }); diff --git a/spec/javascripts/environments/emtpy_state_spec.js b/spec/javascripts/environments/emtpy_state_spec.js index d71dfe8197e..1f986d49bc7 100644 --- a/spec/javascripts/environments/emtpy_state_spec.js +++ b/spec/javascripts/environments/emtpy_state_spec.js @@ -1,4 +1,3 @@ - import Vue from 'vue'; import emptyState from '~/environments/components/empty_state.vue'; import mountComponent from 'spec/helpers/vue_mount_component_helper'; @@ -25,13 +24,13 @@ describe('environments empty state', () => { }); it('renders empty state and new environment button', () => { - expect( - vm.$el.querySelector('.js-blank-state-title').textContent.trim(), - ).toEqual('You don\'t have any environments right now'); + expect(vm.$el.querySelector('.js-blank-state-title').textContent.trim()).toEqual( + "You don't have any environments right now", + ); - expect( - vm.$el.querySelector('.js-new-environment-button').getAttribute('href'), - ).toEqual('foo'); + expect(vm.$el.querySelector('.js-new-environment-button').getAttribute('href')).toEqual( + 'foo', + ); }); }); @@ -45,13 +44,11 @@ describe('environments empty state', () => { }); it('renders empty state without new button', () => { - expect( - vm.$el.querySelector('.js-blank-state-title').textContent.trim(), - ).toEqual('You don\'t have any environments right now'); + expect(vm.$el.querySelector('.js-blank-state-title').textContent.trim()).toEqual( + "You don't have any environments right now", + ); - expect( - vm.$el.querySelector('.js-new-environment-button'), - ).toBeNull(); + expect(vm.$el.querySelector('.js-new-environment-button')).toBeNull(); }); }); }); diff --git a/spec/javascripts/environments/environment_item_spec.js b/spec/javascripts/environments/environment_item_spec.js index 0b933dda431..7618c2f50ce 100644 --- a/spec/javascripts/environments/environment_item_spec.js +++ b/spec/javascripts/environments/environment_item_spec.js @@ -38,7 +38,9 @@ describe('Environment item', () => { }); it('Should render the number of children in a badge', () => { - expect(component.$el.querySelector('.folder-name .badge').textContent).toContain(mockItem.size); + expect(component.$el.querySelector('.folder-name .badge').textContent).toContain( + mockItem.size, + ); }); }); @@ -68,7 +70,8 @@ describe('Environment item', () => { username: 'root', id: 1, state: 'active', - avatar_url: 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon', + avatar_url: + 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon', web_url: 'http://localhost:3000/root', }, commit: { @@ -84,7 +87,8 @@ describe('Environment item', () => { username: 'root', id: 1, state: 'active', - avatar_url: 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon', + avatar_url: + 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon', web_url: 'http://localhost:3000/root', }, commit_path: '/root/ci-folders/tree/500aabcb17c97bdcf2d0c410b70cb8556f0362dd', @@ -121,18 +125,18 @@ describe('Environment item', () => { }); it('should render environment name', () => { - expect(component.$el.querySelector('.environment-name').textContent).toContain(environment.name); + expect(component.$el.querySelector('.environment-name').textContent).toContain( + environment.name, + ); }); describe('With deployment', () => { it('should render deployment internal id', () => { - expect( - component.$el.querySelector('.deployment-column span').textContent, - ).toContain(environment.last_deployment.iid); + expect(component.$el.querySelector('.deployment-column span').textContent).toContain( + environment.last_deployment.iid, + ); - expect( - component.$el.querySelector('.deployment-column span').textContent, - ).toContain('#'); + expect(component.$el.querySelector('.deployment-column span').textContent).toContain('#'); }); it('should render last deployment date', () => { @@ -156,56 +160,46 @@ describe('Environment item', () => { describe('With build url', () => { it('Should link to build url provided', () => { - expect( - component.$el.querySelector('.build-link').getAttribute('href'), - ).toEqual(environment.last_deployment.deployable.build_path); + expect(component.$el.querySelector('.build-link').getAttribute('href')).toEqual( + environment.last_deployment.deployable.build_path, + ); }); it('Should render deployable name and id', () => { - expect( - component.$el.querySelector('.build-link').getAttribute('href'), - ).toEqual(environment.last_deployment.deployable.build_path); + expect(component.$el.querySelector('.build-link').getAttribute('href')).toEqual( + environment.last_deployment.deployable.build_path, + ); }); }); describe('With commit information', () => { it('should render commit component', () => { - expect( - component.$el.querySelector('.js-commit-component'), - ).toBeDefined(); + expect(component.$el.querySelector('.js-commit-component')).toBeDefined(); }); }); }); describe('With manual actions', () => { it('Should render actions component', () => { - expect( - component.$el.querySelector('.js-manual-actions-container'), - ).toBeDefined(); + expect(component.$el.querySelector('.js-manual-actions-container')).toBeDefined(); }); }); describe('With external URL', () => { it('should render external url component', () => { - expect( - component.$el.querySelector('.js-external-url-container'), - ).toBeDefined(); + expect(component.$el.querySelector('.js-external-url-container')).toBeDefined(); }); }); describe('With stop action', () => { it('Should render stop action component', () => { - expect( - component.$el.querySelector('.js-stop-component-container'), - ).toBeDefined(); + expect(component.$el.querySelector('.js-stop-component-container')).toBeDefined(); }); }); describe('With retry action', () => { it('Should render rollback component', () => { - expect( - component.$el.querySelector('.js-rollback-component-container'), - ).toBeDefined(); + expect(component.$el.querySelector('.js-rollback-component-container')).toBeDefined(); }); }); }); diff --git a/spec/javascripts/environments/environments_app_spec.js b/spec/javascripts/environments/environments_app_spec.js index 7edc0ccac0b..ffa11e09597 100644 --- a/spec/javascripts/environments/environments_app_spec.js +++ b/spec/javascripts/environments/environments_app_spec.js @@ -33,7 +33,7 @@ describe('Environment', () => { describe('successfull request', () => { describe('without environments', () => { - beforeEach((done) => { + beforeEach(done => { mock.onGet(mockData.endpoint).reply(200, { environments: [] }); component = mountComponent(EnvironmentsComponent, mockData); @@ -44,30 +44,34 @@ describe('Environment', () => { }); it('should render the empty state', () => { - expect( - component.$el.querySelector('.js-new-environment-button').textContent, - ).toContain('New environment'); + expect(component.$el.querySelector('.js-new-environment-button').textContent).toContain( + 'New environment', + ); - expect( - component.$el.querySelector('.js-blank-state-title').textContent, - ).toContain('You don\'t have any environments right now'); + expect(component.$el.querySelector('.js-blank-state-title').textContent).toContain( + "You don't have any environments right now", + ); }); }); describe('with paginated environments', () => { - beforeEach((done) => { - mock.onGet(mockData.endpoint).reply(200, { - environments: [environment], - stopped_count: 1, - available_count: 0, - }, { - 'X-nExt-pAge': '2', - 'x-page': '1', - 'X-Per-Page': '1', - 'X-Prev-Page': '', - 'X-TOTAL': '37', - 'X-Total-Pages': '2', - }); + beforeEach(done => { + mock.onGet(mockData.endpoint).reply( + 200, + { + environments: [environment], + stopped_count: 1, + available_count: 0, + }, + { + 'X-nExt-pAge': '2', + 'x-page': '1', + 'X-Per-Page': '1', + 'X-Prev-Page': '', + 'X-TOTAL': '37', + 'X-Total-Pages': '2', + }, + ); component = mountComponent(EnvironmentsComponent, mockData); @@ -78,19 +82,17 @@ describe('Environment', () => { it('should render a table with environments', () => { expect(component.$el.querySelectorAll('table')).not.toBeNull(); - expect( - component.$el.querySelector('.environment-name').textContent.trim(), - ).toEqual(environment.name); + expect(component.$el.querySelector('.environment-name').textContent.trim()).toEqual( + environment.name, + ); }); describe('pagination', () => { it('should render pagination', () => { - expect( - component.$el.querySelectorAll('.gl-pagination li').length, - ).toEqual(5); + expect(component.$el.querySelectorAll('.gl-pagination li').length).toEqual(5); }); - it('should make an API request when page is clicked', (done) => { + it('should make an API request when page is clicked', done => { spyOn(component, 'updateContent'); setTimeout(() => { component.$el.querySelector('.gl-pagination li:nth-child(5) a').click(); @@ -100,7 +102,7 @@ describe('Environment', () => { }, 0); }); - it('should make an API request when using tabs', (done) => { + it('should make an API request when using tabs', done => { setTimeout(() => { spyOn(component, 'updateContent'); component.$el.querySelector('.js-environments-tab-stopped').click(); @@ -114,7 +116,7 @@ describe('Environment', () => { }); describe('unsuccessfull request', () => { - beforeEach((done) => { + beforeEach(done => { mock.onGet(mockData.endpoint).reply(500, {}); component = mountComponent(EnvironmentsComponent, mockData); @@ -125,15 +127,16 @@ describe('Environment', () => { }); it('should render empty state', () => { - expect( - component.$el.querySelector('.js-blank-state-title').textContent, - ).toContain('You don\'t have any environments right now'); + expect(component.$el.querySelector('.js-blank-state-title').textContent).toContain( + "You don't have any environments right now", + ); }); }); describe('expandable folders', () => { beforeEach(() => { - mock.onGet(mockData.endpoint).reply(200, + mock.onGet(mockData.endpoint).reply( + 200, { environments: [folder], stopped_count: 0, @@ -154,7 +157,7 @@ describe('Environment', () => { component = mountComponent(EnvironmentsComponent, mockData); }); - it('should open a closed folder', (done) => { + it('should open a closed folder', done => { setTimeout(() => { component.$el.querySelector('.folder-name').click(); @@ -165,7 +168,7 @@ describe('Environment', () => { }, 0); }); - it('should close an opened folder', (done) => { + it('should close an opened folder', done => { setTimeout(() => { // open folder component.$el.querySelector('.folder-name').click(); @@ -182,7 +185,7 @@ describe('Environment', () => { }, 0); }); - it('should show children environments and a button to show all environments', (done) => { + it('should show children environments and a button to show all environments', done => { setTimeout(() => { // open folder component.$el.querySelector('.folder-name').click(); @@ -191,7 +194,9 @@ describe('Environment', () => { // wait for next async request setTimeout(() => { expect(component.$el.querySelectorAll('.js-child-row').length).toEqual(1); - expect(component.$el.querySelector('.text-center > a.btn').textContent).toContain('Show all'); + expect(component.$el.querySelector('.text-center > a.btn').textContent).toContain( + 'Show all', + ); done(); }); }); @@ -201,7 +206,8 @@ describe('Environment', () => { describe('methods', () => { beforeEach(() => { - mock.onGet(mockData.endpoint).reply(200, + mock.onGet(mockData.endpoint).reply( + 200, { environments: [], stopped_count: 0, @@ -215,8 +221,9 @@ describe('Environment', () => { }); describe('updateContent', () => { - it('should set given parameters', (done) => { - component.updateContent({ scope: 'stopped', page: '3' }) + it('should set given parameters', done => { + component + .updateContent({ scope: 'stopped', page: '3' }) .then(() => { expect(component.page).toEqual('3'); expect(component.scope).toEqual('stopped'); diff --git a/spec/javascripts/environments/folder/environments_folder_view_spec.js b/spec/javascripts/environments/folder/environments_folder_view_spec.js index 51d4213c38f..862473b5c58 100644 --- a/spec/javascripts/environments/folder/environments_folder_view_spec.js +++ b/spec/javascripts/environments/folder/environments_folder_view_spec.js @@ -32,37 +32,41 @@ describe('Environments Folder View', () => { describe('successfull request', () => { beforeEach(() => { - mock.onGet(mockData.endpoint).reply(200, { - environments: environmentsList, - stopped_count: 1, - available_count: 0, - }, { - 'X-nExt-pAge': '2', - 'x-page': '1', - 'X-Per-Page': '2', - 'X-Prev-Page': '', - 'X-TOTAL': '20', - 'X-Total-Pages': '10', - }); + mock.onGet(mockData.endpoint).reply( + 200, + { + environments: environmentsList, + stopped_count: 1, + available_count: 0, + }, + { + 'X-nExt-pAge': '2', + 'x-page': '1', + 'X-Per-Page': '2', + 'X-Prev-Page': '', + 'X-TOTAL': '20', + 'X-Total-Pages': '10', + }, + ); component = mountComponent(Component, mockData); }); - it('should render a table with environments', (done) => { + it('should render a table with environments', done => { setTimeout(() => { expect(component.$el.querySelectorAll('table')).not.toBeNull(); - expect( - component.$el.querySelector('.environment-name').textContent.trim(), - ).toEqual(environmentsList[0].name); + expect(component.$el.querySelector('.environment-name').textContent.trim()).toEqual( + environmentsList[0].name, + ); done(); }, 0); }); - it('should render available tab with count', (done) => { + it('should render available tab with count', done => { setTimeout(() => { - expect( - component.$el.querySelector('.js-environments-tab-available').textContent, - ).toContain('Available'); + expect(component.$el.querySelector('.js-environments-tab-available').textContent).toContain( + 'Available', + ); expect( component.$el.querySelector('.js-environments-tab-available .badge').textContent, @@ -71,11 +75,11 @@ describe('Environments Folder View', () => { }, 0); }); - it('should render stopped tab with count', (done) => { + it('should render stopped tab with count', done => { setTimeout(() => { - expect( - component.$el.querySelector('.js-environments-tab-stopped').textContent, - ).toContain('Stopped'); + expect(component.$el.querySelector('.js-environments-tab-stopped').textContent).toContain( + 'Stopped', + ); expect( component.$el.querySelector('.js-environments-tab-stopped .badge').textContent, @@ -84,36 +88,37 @@ describe('Environments Folder View', () => { }, 0); }); - it('should render parent folder name', (done) => { + it('should render parent folder name', done => { setTimeout(() => { - expect( - component.$el.querySelector('.js-folder-name').textContent.trim(), - ).toContain('Environments / review'); + expect(component.$el.querySelector('.js-folder-name').textContent.trim()).toContain( + 'Environments / review', + ); done(); }, 0); }); describe('pagination', () => { - it('should render pagination', (done) => { + it('should render pagination', done => { setTimeout(() => { - expect( - component.$el.querySelectorAll('.gl-pagination'), - ).not.toBeNull(); + expect(component.$el.querySelectorAll('.gl-pagination')).not.toBeNull(); done(); }, 0); }); - it('should make an API request when changing page', (done) => { + it('should make an API request when changing page', done => { spyOn(component, 'updateContent'); setTimeout(() => { component.$el.querySelector('.gl-pagination .js-last-button a').click(); - expect(component.updateContent).toHaveBeenCalledWith({ scope: component.scope, page: '10' }); + expect(component.updateContent).toHaveBeenCalledWith({ + scope: component.scope, + page: '10', + }); done(); }, 0); }); - it('should make an API request when using tabs', (done) => { + it('should make an API request when using tabs', done => { setTimeout(() => { spyOn(component, 'updateContent'); component.$el.querySelector('.js-environments-tab-stopped').click(); @@ -134,20 +139,18 @@ describe('Environments Folder View', () => { component = mountComponent(Component, mockData); }); - it('should not render a table', (done) => { + it('should not render a table', done => { setTimeout(() => { - expect( - component.$el.querySelector('table'), - ).toBe(null); + expect(component.$el.querySelector('table')).toBe(null); done(); }, 0); }); - it('should render available tab with count 0', (done) => { + it('should render available tab with count 0', done => { setTimeout(() => { - expect( - component.$el.querySelector('.js-environments-tab-available').textContent, - ).toContain('Available'); + expect(component.$el.querySelector('.js-environments-tab-available').textContent).toContain( + 'Available', + ); expect( component.$el.querySelector('.js-environments-tab-available .badge').textContent, @@ -156,11 +159,11 @@ describe('Environments Folder View', () => { }, 0); }); - it('should render stopped tab with count 0', (done) => { + it('should render stopped tab with count 0', done => { setTimeout(() => { - expect( - component.$el.querySelector('.js-environments-tab-stopped').textContent, - ).toContain('Stopped'); + expect(component.$el.querySelector('.js-environments-tab-stopped').textContent).toContain( + 'Stopped', + ); expect( component.$el.querySelector('.js-environments-tab-stopped .badge').textContent, @@ -181,8 +184,9 @@ describe('Environments Folder View', () => { }); describe('updateContent', () => { - it('should set given parameters', (done) => { - component.updateContent({ scope: 'stopped', page: '4' }) + it('should set given parameters', done => { + component + .updateContent({ scope: 'stopped', page: '4' }) .then(() => { expect(component.page).toEqual('4'); expect(component.scope).toEqual('stopped'); diff --git a/spec/javascripts/issue_show/components/title_spec.js b/spec/javascripts/issue_show/components/title_spec.js index 9e6f236b687..9754c8a6755 100644 --- a/spec/javascripts/issue_show/components/title_spec.js +++ b/spec/javascripts/issue_show/components/title_spec.js @@ -25,25 +25,21 @@ describe('Title component', () => { }); it('renders title HTML', () => { - expect( - vm.$el.querySelector('.title').innerHTML.trim(), - ).toBe('Testing <img>'); + expect(vm.$el.querySelector('.title').innerHTML.trim()).toBe('Testing <img>'); }); - it('updates page title when changing titleHtml', (done) => { + it('updates page title when changing titleHtml', done => { spyOn(vm, 'setPageTitle'); vm.titleHtml = 'test'; Vue.nextTick(() => { - expect( - vm.setPageTitle, - ).toHaveBeenCalled(); + expect(vm.setPageTitle).toHaveBeenCalled(); done(); }); }); - it('animates title changes', (done) => { + it('animates title changes', done => { vm.titleHtml = 'test'; Vue.nextTick(() => { @@ -61,14 +57,12 @@ describe('Title component', () => { }); }); - it('updates page title after changing title', (done) => { + it('updates page title after changing title', done => { vm.titleHtml = 'changed'; vm.titleText = 'changed'; Vue.nextTick(() => { - expect( - document.querySelector('title').textContent.trim(), - ).toContain('changed'); + expect(document.querySelector('title').textContent.trim()).toContain('changed'); done(); }); diff --git a/spec/javascripts/jobs/components/job_app_spec.js b/spec/javascripts/jobs/components/job_app_spec.js index 288c06d6615..49c55202328 100644 --- a/spec/javascripts/jobs/components/job_app_spec.js +++ b/spec/javascripts/jobs/components/job_app_spec.js @@ -234,7 +234,7 @@ describe('Job App ', () => { ); done(); }, 0); - }) + }); }); it('does not renders stuck block when there are no runners', done => { diff --git a/spec/javascripts/jobs/store/actions_spec.js b/spec/javascripts/jobs/store/actions_spec.js index 45130b983e7..77b44995b12 100644 --- a/spec/javascripts/jobs/store/actions_spec.js +++ b/spec/javascripts/jobs/store/actions_spec.js @@ -68,41 +68,20 @@ describe('Job State actions', () => { describe('hideSidebar', () => { it('should commit HIDE_SIDEBAR mutation', done => { - testAction( - hideSidebar, - null, - mockedState, - [{ type: types.HIDE_SIDEBAR }], - [], - done, - ); + testAction(hideSidebar, null, mockedState, [{ type: types.HIDE_SIDEBAR }], [], done); }); }); describe('showSidebar', () => { it('should commit HIDE_SIDEBAR mutation', done => { - testAction( - showSidebar, - null, - mockedState, - [{ type: types.SHOW_SIDEBAR }], - [], - done, - ); + testAction(showSidebar, null, mockedState, [{ type: types.SHOW_SIDEBAR }], [], done); }); }); describe('toggleSidebar', () => { describe('when isSidebarOpen is true', () => { it('should dispatch hideSidebar', done => { - testAction( - toggleSidebar, - null, - mockedState, - [], - [{ type: 'hideSidebar' }], - done, - ); + testAction(toggleSidebar, null, mockedState, [], [{ type: 'hideSidebar' }], done); }); }); @@ -110,14 +89,7 @@ describe('Job State actions', () => { it('should dispatch showSidebar', done => { mockedState.isSidebarOpen = false; - testAction( - toggleSidebar, - null, - mockedState, - [], - [{ type: 'showSidebar' }], - done, - ); + testAction(toggleSidebar, null, mockedState, [], [{ type: 'showSidebar' }], done); }); }); }); diff --git a/spec/javascripts/jobs/store/getters_spec.js b/spec/javascripts/jobs/store/getters_spec.js index 34e9707eadd..4195d9d3680 100644 --- a/spec/javascripts/jobs/store/getters_spec.js +++ b/spec/javascripts/jobs/store/getters_spec.js @@ -180,7 +180,7 @@ describe('Job Store Getters', () => { it('returns true', () => { localState.job.runners = { available: true, - online: false + online: false, }; expect(getters.hasRunnersForProject(localState)).toEqual(true); @@ -191,7 +191,7 @@ describe('Job Store Getters', () => { it('returns false', () => { localState.job.runners = { available: false, - online: false + online: false, }; expect(getters.hasRunnersForProject(localState)).toEqual(false); @@ -202,7 +202,7 @@ describe('Job Store Getters', () => { it('returns false', () => { localState.job.runners = { available: false, - online: true + online: true, }; expect(getters.hasRunnersForProject(localState)).toEqual(false); diff --git a/spec/javascripts/lib/utils/common_utils_spec.js b/spec/javascripts/lib/utils/common_utils_spec.js index 514d6ddeae5..efff233451e 100644 --- a/spec/javascripts/lib/utils/common_utils_spec.js +++ b/spec/javascripts/lib/utils/common_utils_spec.js @@ -35,9 +35,7 @@ describe('common_utils', () => { }); it('should decode params', () => { - expect( - commonUtils.urlParamsToArray('?label_name%5B%5D=test')[0], - ).toBe('label_name[]=test'); + expect(commonUtils.urlParamsToArray('?label_name%5B%5D=test')[0]).toBe('label_name[]=test'); }); it('should remove the question mark from the search params', () => { @@ -49,25 +47,19 @@ describe('common_utils', () => { describe('urlParamsToObject', () => { it('parses path for label with trailing +', () => { - expect( - commonUtils.urlParamsToObject('label_name[]=label%2B', {}), - ).toEqual({ + expect(commonUtils.urlParamsToObject('label_name[]=label%2B', {})).toEqual({ label_name: ['label+'], }); }); it('parses path for milestone with trailing +', () => { - expect( - commonUtils.urlParamsToObject('milestone_title=A%2B', {}), - ).toEqual({ + expect(commonUtils.urlParamsToObject('milestone_title=A%2B', {})).toEqual({ milestone_title: 'A+', }); }); it('parses path for search terms with spaces', () => { - expect( - commonUtils.urlParamsToObject('search=two+words', {}), - ).toEqual({ + expect(commonUtils.urlParamsToObject('search=two+words', {})).toEqual({ search: 'two words', }); }); @@ -187,7 +179,10 @@ describe('common_utils', () => { describe('parseQueryStringIntoObject', () => { it('should return object with query parameters', () => { - expect(commonUtils.parseQueryStringIntoObject('scope=all&page=2')).toEqual({ scope: 'all', page: '2' }); + expect(commonUtils.parseQueryStringIntoObject('scope=all&page=2')).toEqual({ + scope: 'all', + page: '2', + }); expect(commonUtils.parseQueryStringIntoObject('scope=all')).toEqual({ scope: 'all' }); expect(commonUtils.parseQueryStringIntoObject()).toEqual({}); }); @@ -211,7 +206,9 @@ describe('common_utils', () => { describe('buildUrlWithCurrentLocation', () => { it('should build an url with current location and given parameters', () => { expect(commonUtils.buildUrlWithCurrentLocation()).toEqual(window.location.pathname); - expect(commonUtils.buildUrlWithCurrentLocation('?page=2')).toEqual(`${window.location.pathname}?page=2`); + expect(commonUtils.buildUrlWithCurrentLocation('?page=2')).toEqual( + `${window.location.pathname}?page=2`, + ); }); }); @@ -266,21 +263,24 @@ describe('common_utils', () => { }); describe('normalizeCRLFHeaders', () => { - beforeEach(function () { - this.CLRFHeaders = 'a-header: a-value\nAnother-Header: ANOTHER-VALUE\nLaSt-HeAdEr: last-VALUE'; + beforeEach(function() { + this.CLRFHeaders = + 'a-header: a-value\nAnother-Header: ANOTHER-VALUE\nLaSt-HeAdEr: last-VALUE'; spyOn(String.prototype, 'split').and.callThrough(); this.normalizeCRLFHeaders = commonUtils.normalizeCRLFHeaders(this.CLRFHeaders); }); - it('should split by newline', function () { + it('should split by newline', function() { expect(String.prototype.split).toHaveBeenCalledWith('\n'); }); - it('should split by colon+space for each header', function () { - expect(String.prototype.split.calls.allArgs().filter(args => args[0] === ': ').length).toBe(3); + it('should split by colon+space for each header', function() { + expect(String.prototype.split.calls.allArgs().filter(args => args[0] === ': ').length).toBe( + 3, + ); }); - it('should return a normalized headers object', function () { + it('should return a normalized headers object', function() { expect(this.normalizeCRLFHeaders).toEqual({ 'A-HEADER': 'a-value', 'ANOTHER-HEADER': 'ANOTHER-VALUE', @@ -359,67 +359,79 @@ describe('common_utils', () => { spyOn(window, 'setTimeout').and.callFake(cb => origSetTimeout(cb, 0)); }); - it('solves the promise from the callback', (done) => { + it('solves the promise from the callback', done => { const expectedResponseValue = 'Success!'; - commonUtils.backOff((next, stop) => ( - new Promise((resolve) => { - resolve(expectedResponseValue); - }).then((resp) => { - stop(resp); + commonUtils + .backOff((next, stop) => + new Promise(resolve => { + resolve(expectedResponseValue); + }) + .then(resp => { + stop(resp); + }) + .catch(done.fail), + ) + .then(respBackoff => { + expect(respBackoff).toBe(expectedResponseValue); + done(); }) - ).catch(done.fail)).then((respBackoff) => { - expect(respBackoff).toBe(expectedResponseValue); - done(); - }).catch(done.fail); + .catch(done.fail); }); - it('catches the rejected promise from the callback ', (done) => { + it('catches the rejected promise from the callback ', done => { const errorMessage = 'Mistakes were made!'; - commonUtils.backOff((next, stop) => { - new Promise((resolve, reject) => { - reject(new Error(errorMessage)); - }).then((resp) => { - stop(resp); - }).catch(err => stop(err)); - }).catch((errBackoffResp) => { - expect(errBackoffResp instanceof Error).toBe(true); - expect(errBackoffResp.message).toBe(errorMessage); - done(); - }); + commonUtils + .backOff((next, stop) => { + new Promise((resolve, reject) => { + reject(new Error(errorMessage)); + }) + .then(resp => { + stop(resp); + }) + .catch(err => stop(err)); + }) + .catch(errBackoffResp => { + expect(errBackoffResp instanceof Error).toBe(true); + expect(errBackoffResp.message).toBe(errorMessage); + done(); + }); }); - it('solves the promise correctly after retrying a third time', (done) => { + it('solves the promise correctly after retrying a third time', done => { let numberOfCalls = 1; const expectedResponseValue = 'Success!'; - commonUtils.backOff((next, stop) => ( - Promise.resolve(expectedResponseValue) - .then((resp) => { - if (numberOfCalls < 3) { - numberOfCalls += 1; - next(); - } else { - stop(resp); - } - }) - ).catch(done.fail)).then((respBackoff) => { - const timeouts = window.setTimeout.calls.allArgs().map(([, timeout]) => timeout); + commonUtils + .backOff((next, stop) => + Promise.resolve(expectedResponseValue) + .then(resp => { + if (numberOfCalls < 3) { + numberOfCalls += 1; + next(); + } else { + stop(resp); + } + }) + .catch(done.fail), + ) + .then(respBackoff => { + const timeouts = window.setTimeout.calls.allArgs().map(([, timeout]) => timeout); - expect(timeouts).toEqual([2000, 4000]); - expect(respBackoff).toBe(expectedResponseValue); - done(); - }).catch(done.fail); + expect(timeouts).toEqual([2000, 4000]); + expect(respBackoff).toBe(expectedResponseValue); + done(); + }) + .catch(done.fail); }); - it('rejects the backOff promise after timing out', (done) => { - commonUtils.backOff(next => next(), 64000) - .catch((errBackoffResp) => { - const timeouts = window.setTimeout.calls.allArgs().map(([, timeout]) => timeout); + it('rejects the backOff promise after timing out', done => { + commonUtils.backOff(next => next(), 64000).catch(errBackoffResp => { + const timeouts = window.setTimeout.calls.allArgs().map(([, timeout]) => timeout); - expect(timeouts).toEqual([2000, 4000, 8000, 16000, 32000, 32000]); - expect(errBackoffResp instanceof Error).toBe(true); - expect(errBackoffResp.message).toBe('BACKOFF_TIMEOUT'); - done(); - }); + expect(timeouts).toEqual([2000, 4000, 8000, 16000, 32000, 32000]); + expect(errBackoffResp instanceof Error).toBe(true); + expect(errBackoffResp.message).toBe('BACKOFF_TIMEOUT'); + done(); + }); }); }); @@ -466,11 +478,14 @@ describe('common_utils', () => { }); describe('createOverlayIcon', () => { - it('should return the favicon with the overlay', (done) => { - commonUtils.createOverlayIcon(faviconDataUrl, overlayDataUrl).then((url) => { - expect(url).toEqual(faviconWithOverlayDataUrl); - done(); - }).catch(done.fail); + it('should return the favicon with the overlay', done => { + commonUtils + .createOverlayIcon(faviconDataUrl, overlayDataUrl) + .then(url => { + expect(url).toEqual(faviconWithOverlayDataUrl); + done(); + }) + .catch(done.fail); }); }); @@ -486,11 +501,16 @@ describe('common_utils', () => { document.body.removeChild(document.getElementById('favicon')); }); - it('should set page favicon to provided favicon overlay', (done) => { - commonUtils.setFaviconOverlay(overlayDataUrl).then(() => { - expect(document.getElementById('favicon').getAttribute('href')).toEqual(faviconWithOverlayDataUrl); - done(); - }).catch(done.fail); + it('should set page favicon to provided favicon overlay', done => { + commonUtils + .setFaviconOverlay(overlayDataUrl) + .then(() => { + expect(document.getElementById('favicon').getAttribute('href')).toEqual( + faviconWithOverlayDataUrl, + ); + done(); + }) + .catch(done.fail); }); }); @@ -512,24 +532,24 @@ describe('common_utils', () => { document.body.removeChild(document.getElementById('favicon')); }); - it('should reset favicon in case of error', (done) => { + it('should reset favicon in case of error', done => { mock.onGet(BUILD_URL).replyOnce(500); - commonUtils.setCiStatusFavicon(BUILD_URL) - .catch(() => { - const favicon = document.getElementById('favicon'); + commonUtils.setCiStatusFavicon(BUILD_URL).catch(() => { + const favicon = document.getElementById('favicon'); - expect(favicon.getAttribute('href')).toEqual(faviconDataUrl); - done(); - }); + expect(favicon.getAttribute('href')).toEqual(faviconDataUrl); + done(); + }); }); - it('should set page favicon to CI status favicon based on provided status', (done) => { + it('should set page favicon to CI status favicon based on provided status', done => { mock.onGet(BUILD_URL).reply(200, { favicon: overlayDataUrl, }); - commonUtils.setCiStatusFavicon(BUILD_URL) + commonUtils + .setCiStatusFavicon(BUILD_URL) .then(() => { const favicon = document.getElementById('favicon'); @@ -554,11 +574,15 @@ describe('common_utils', () => { }); it('should return the svg for a linked icon', () => { - expect(commonUtils.spriteIcon('test')).toEqual('<svg ><use xlink:href="icons.svg#test" /></svg>'); + expect(commonUtils.spriteIcon('test')).toEqual( + '<svg ><use xlink:href="icons.svg#test" /></svg>', + ); }); it('should set svg className when passed', () => { - expect(commonUtils.spriteIcon('test', 'fa fa-test')).toEqual('<svg class="fa fa-test"><use xlink:href="icons.svg#test" /></svg>'); + expect(commonUtils.spriteIcon('test', 'fa fa-test')).toEqual( + '<svg class="fa fa-test"><use xlink:href="icons.svg#test" /></svg>', + ); }); }); @@ -578,7 +602,7 @@ describe('common_utils', () => { const convertedObj = commonUtils.convertObjectPropsToCamelCase(mockObj); - Object.keys(convertedObj).forEach((prop) => { + Object.keys(convertedObj).forEach(prop => { expect(snakeRegEx.test(prop)).toBeFalsy(); expect(convertedObj[prop]).toBe(mockObj[mappings[prop]]); }); @@ -597,9 +621,7 @@ describe('common_utils', () => { }, }; - expect( - commonUtils.convertObjectPropsToCamelCase(obj), - ).toEqual({ + expect(commonUtils.convertObjectPropsToCamelCase(obj)).toEqual({ snakeKey: { child_snake_key: 'value', }, @@ -614,9 +636,7 @@ describe('common_utils', () => { }, }; - expect( - commonUtils.convertObjectPropsToCamelCase(obj, { deep: true }), - ).toEqual({ + expect(commonUtils.convertObjectPropsToCamelCase(obj, { deep: true })).toEqual({ snakeKey: { childSnakeKey: 'value', }, @@ -630,9 +650,7 @@ describe('common_utils', () => { }, ]; - expect( - commonUtils.convertObjectPropsToCamelCase(arr, { deep: true }), - ).toEqual([ + expect(commonUtils.convertObjectPropsToCamelCase(arr, { deep: true })).toEqual([ { childSnakeKey: 'value', }, @@ -648,9 +666,7 @@ describe('common_utils', () => { ], ]; - expect( - commonUtils.convertObjectPropsToCamelCase(arr, { deep: true }), - ).toEqual([ + expect(commonUtils.convertObjectPropsToCamelCase(arr, { deep: true })).toEqual([ [ { childSnakeKey: 'value', diff --git a/spec/javascripts/lib/utils/number_utility_spec.js b/spec/javascripts/lib/utils/number_utility_spec.js index a5099a2a3b8..94c6214c86a 100644 --- a/spec/javascripts/lib/utils/number_utility_spec.js +++ b/spec/javascripts/lib/utils/number_utility_spec.js @@ -1,4 +1,10 @@ -import { formatRelevantDigits, bytesToKiB, bytesToMiB, bytesToGiB, numberToHumanSize } from '~/lib/utils/number_utils'; +import { + formatRelevantDigits, + bytesToKiB, + bytesToMiB, + bytesToGiB, + numberToHumanSize, +} from '~/lib/utils/number_utils'; describe('Number Utils', () => { describe('formatRelevantDigits', () => { diff --git a/spec/javascripts/monitoring/graph/flag_spec.js b/spec/javascripts/monitoring/graph/flag_spec.js index a837b71db0b..038bfffd44f 100644 --- a/spec/javascripts/monitoring/graph/flag_spec.js +++ b/spec/javascripts/monitoring/graph/flag_spec.js @@ -2,7 +2,7 @@ import Vue from 'vue'; import GraphFlag from '~/monitoring/components/graph/flag.vue'; import { deploymentData } from '../mock_data'; -const createComponent = (propsData) => { +const createComponent = propsData => { const Component = Vue.extend(GraphFlag); return new Component({ @@ -51,8 +51,7 @@ describe('GraphFlag', () => { it('has a line at the currentXCoordinate', () => { component = createComponent(defaultValuesComponent); - expect(component.$el.style.left) - .toEqual(`${70 + component.currentXCoordinate}px`); + expect(component.$el.style.left).toEqual(`${70 + component.currentXCoordinate}px`); }); describe('Deployment flag', () => { @@ -62,9 +61,7 @@ describe('GraphFlag', () => { deploymentFlagData, }); - expect( - deploymentFlagComponent.$el.querySelector('.popover-title'), - ).toContainText('Deployed'); + expect(deploymentFlagComponent.$el.querySelector('.popover-title')).toContainText('Deployed'); }); it('contains the ref when a tag is available', () => { @@ -78,13 +75,13 @@ describe('GraphFlag', () => { }, }); - expect( - deploymentFlagComponent.$el.querySelector('.deploy-meta-content'), - ).toContainText('f5bcd1d9'); + expect(deploymentFlagComponent.$el.querySelector('.deploy-meta-content')).toContainText( + 'f5bcd1d9', + ); - expect( - deploymentFlagComponent.$el.querySelector('.deploy-meta-content'), - ).toContainText('1.0'); + expect(deploymentFlagComponent.$el.querySelector('.deploy-meta-content')).toContainText( + '1.0', + ); }); it('does not contain the ref when a tag is unavailable', () => { @@ -98,13 +95,13 @@ describe('GraphFlag', () => { }, }); - expect( - deploymentFlagComponent.$el.querySelector('.deploy-meta-content'), - ).toContainText('f5bcd1d9'); + expect(deploymentFlagComponent.$el.querySelector('.deploy-meta-content')).toContainText( + 'f5bcd1d9', + ); - expect( - deploymentFlagComponent.$el.querySelector('.deploy-meta-content'), - ).not.toContainText('1.0'); + expect(deploymentFlagComponent.$el.querySelector('.deploy-meta-content')).not.toContainText( + '1.0', + ); }); }); diff --git a/spec/javascripts/notes/components/discussion_filter_spec.js b/spec/javascripts/notes/components/discussion_filter_spec.js index 70dd5bb3be5..a81bdf618a3 100644 --- a/spec/javascripts/notes/components/discussion_filter_spec.js +++ b/spec/javascripts/notes/components/discussion_filter_spec.js @@ -11,11 +11,13 @@ describe('DiscussionFilter component', () => { beforeEach(() => { store = createStore(); - const discussions = [{ - ...discussionMock, - id: discussionMock.id, - notes: [{ ...discussionMock.notes[0], resolvable: true, resolved: true }], - }]; + const discussions = [ + { + ...discussionMock, + id: discussionMock.id, + notes: [{ ...discussionMock.notes[0], resolvable: true, resolved: true }], + }, + ]; const Component = Vue.extend(DiscussionFilter); const defaultValue = discussionFiltersMock[0].value; @@ -35,11 +37,15 @@ describe('DiscussionFilter component', () => { }); it('renders the all filters', () => { - expect(vm.$el.querySelectorAll('.dropdown-menu li').length).toEqual(discussionFiltersMock.length); + expect(vm.$el.querySelectorAll('.dropdown-menu li').length).toEqual( + discussionFiltersMock.length, + ); }); it('renders the default selected item', () => { - expect(vm.$el.querySelector('#discussion-filter-dropdown').textContent.trim()).toEqual(discussionFiltersMock[0].title); + expect(vm.$el.querySelector('#discussion-filter-dropdown').textContent.trim()).toEqual( + discussionFiltersMock[0].title, + ); }); it('updates to the selected item', () => { diff --git a/spec/javascripts/notes/components/note_app_spec.js b/spec/javascripts/notes/components/note_app_spec.js index 06b30375306..3e289a6b8e6 100644 --- a/spec/javascripts/notes/components/note_app_spec.js +++ b/spec/javascripts/notes/components/note_app_spec.js @@ -97,7 +97,8 @@ describe('note_app', () => { }); it('should render list of notes', done => { - const note = mockData.INDIVIDUAL_NOTE_RESPONSE_MAP.GET[ + const note = + mockData.INDIVIDUAL_NOTE_RESPONSE_MAP.GET[ '/gitlab-org/gitlab-ce/issues/26/discussions.json' ][0].notes[0]; diff --git a/spec/javascripts/pipelines/graph/graph_component_spec.js b/spec/javascripts/pipelines/graph/graph_component_spec.js index b6fa4272c8b..96a2d5f62fa 100644 --- a/spec/javascripts/pipelines/graph/graph_component_spec.js +++ b/spec/javascripts/pipelines/graph/graph_component_spec.js @@ -40,7 +40,9 @@ describe('graph component', () => { ).toEqual(true); expect( - component.$el.querySelector('.stage-column:nth-child(2) .build:nth-child(1)').classList.contains('left-connector'), + component.$el + .querySelector('.stage-column:nth-child(2) .build:nth-child(1)') + .classList.contains('left-connector'), ).toEqual(true); expect(component.$el.querySelector('loading-icon')).toBe(null); @@ -56,7 +58,9 @@ describe('graph component', () => { pipeline: graphJSON, }); - expect(component.$el.querySelector('.stage-column:nth-child(2) .stage-name').textContent.trim()).toEqual('Deploy <img src=x onerror=alert(document.domain)>'); + expect( + component.$el.querySelector('.stage-column:nth-child(2) .stage-name').textContent.trim(), + ).toEqual('Deploy <img src=x onerror=alert(document.domain)>'); }); }); }); diff --git a/spec/javascripts/sidebar/assignees_spec.js b/spec/javascripts/sidebar/assignees_spec.js index e7f8f4f9936..6076fb07bc9 100644 --- a/spec/javascripts/sidebar/assignees_spec.js +++ b/spec/javascripts/sidebar/assignees_spec.js @@ -78,9 +78,7 @@ describe('Assignee component', () => { component = new AssigneeComponent({ propsData: { rootPath: 'http://localhost:3000', - users: [ - UsersMock.user, - ], + users: [UsersMock.user], editable: false, }, }).$mount(); @@ -90,7 +88,9 @@ describe('Assignee component', () => { expect(collapsed.childElementCount).toEqual(1); expect(assignee.querySelector('.avatar').getAttribute('src')).toEqual(UsersMock.user.avatar); - expect(assignee.querySelector('.avatar').getAttribute('alt')).toEqual(`${UsersMock.user.name}'s avatar`); + expect(assignee.querySelector('.avatar').getAttribute('alt')).toEqual( + `${UsersMock.user.name}'s avatar`, + ); expect(assignee.querySelector('.author').innerText.trim()).toEqual(UsersMock.user.name); }); @@ -98,34 +98,38 @@ describe('Assignee component', () => { component = new AssigneeComponent({ propsData: { rootPath: 'http://localhost:3000/', - users: [ - UsersMock.user, - ], + users: [UsersMock.user], editable: true, }, }).$mount(); expect(component.$el.querySelector('.author-link')).not.toBeNull(); // The image - expect(component.$el.querySelector('.author-link img').getAttribute('src')).toEqual(UsersMock.user.avatar); + expect(component.$el.querySelector('.author-link img').getAttribute('src')).toEqual( + UsersMock.user.avatar, + ); // Author name - expect(component.$el.querySelector('.author-link .author').innerText.trim()).toEqual(UsersMock.user.name); + expect(component.$el.querySelector('.author-link .author').innerText.trim()).toEqual( + UsersMock.user.name, + ); // Username - expect(component.$el.querySelector('.author-link .username').innerText.trim()).toEqual(`@${UsersMock.user.username}`); + expect(component.$el.querySelector('.author-link .username').innerText.trim()).toEqual( + `@${UsersMock.user.username}`, + ); }); it('has the root url present in the assigneeUrl method', () => { component = new AssigneeComponent({ propsData: { rootPath: 'http://localhost:3000/', - users: [ - UsersMock.user, - ], + users: [UsersMock.user], editable: true, }, }).$mount(); - expect(component.assigneeUrl(UsersMock.user).indexOf('http://localhost:3000/')).not.toEqual(-1); + expect(component.assigneeUrl(UsersMock.user).indexOf('http://localhost:3000/')).not.toEqual( + -1, + ); }); }); @@ -147,13 +151,17 @@ describe('Assignee component', () => { const first = collapsed.children[0]; expect(first.querySelector('.avatar').getAttribute('src')).toEqual(users[0].avatar); - expect(first.querySelector('.avatar').getAttribute('alt')).toEqual(`${users[0].name}'s avatar`); + expect(first.querySelector('.avatar').getAttribute('alt')).toEqual( + `${users[0].name}'s avatar`, + ); expect(first.querySelector('.author').innerText.trim()).toEqual(users[0].name); const second = collapsed.children[1]; expect(second.querySelector('.avatar').getAttribute('src')).toEqual(users[1].avatar); - expect(second.querySelector('.avatar').getAttribute('alt')).toEqual(`${users[1].name}'s avatar`); + expect(second.querySelector('.avatar').getAttribute('alt')).toEqual( + `${users[1].name}'s avatar`, + ); expect(second.querySelector('.author').innerText.trim()).toEqual(users[1].name); }); @@ -174,7 +182,9 @@ describe('Assignee component', () => { const first = collapsed.children[0]; expect(first.querySelector('.avatar').getAttribute('src')).toEqual(users[0].avatar); - expect(first.querySelector('.avatar').getAttribute('alt')).toEqual(`${users[0].name}'s avatar`); + expect(first.querySelector('.avatar').getAttribute('alt')).toEqual( + `${users[0].name}'s avatar`, + ); expect(first.querySelector('.author').innerText.trim()).toEqual(users[0].name); const second = collapsed.children[1]; @@ -196,7 +206,7 @@ describe('Assignee component', () => { expect(component.$el.querySelector('.user-list-more')).toBe(null); }); - it('Shows the "show-less" assignees label', (done) => { + it('Shows the "show-less" assignees label', done => { const users = UsersMockHelper.createNumberRandomUsers(6); component = new AssigneeComponent({ propsData: { @@ -206,21 +216,25 @@ describe('Assignee component', () => { }, }).$mount(); - expect(component.$el.querySelectorAll('.user-item').length).toEqual(component.defaultRenderCount); + expect(component.$el.querySelectorAll('.user-item').length).toEqual( + component.defaultRenderCount, + ); expect(component.$el.querySelector('.user-list-more')).not.toBe(null); const usersLabelExpectation = users.length - component.defaultRenderCount; - expect(component.$el.querySelector('.user-list-more .btn-link').innerText.trim()) - .not.toBe(`+${usersLabelExpectation} more`); + expect(component.$el.querySelector('.user-list-more .btn-link').innerText.trim()).not.toBe( + `+${usersLabelExpectation} more`, + ); component.toggleShowLess(); Vue.nextTick(() => { - expect(component.$el.querySelector('.user-list-more .btn-link').innerText.trim()) - .toBe('- show less'); + expect(component.$el.querySelector('.user-list-more .btn-link').innerText.trim()).toBe( + '- show less', + ); done(); }); }); - it('Shows the "show-less" when "n+ more " label is clicked', (done) => { + it('Shows the "show-less" when "n+ more " label is clicked', done => { const users = UsersMockHelper.createNumberRandomUsers(6); component = new AssigneeComponent({ propsData: { @@ -232,8 +246,9 @@ describe('Assignee component', () => { component.$el.querySelector('.user-list-more .btn-link').click(); Vue.nextTick(() => { - expect(component.$el.querySelector('.user-list-more .btn-link').innerText.trim()) - .toBe('- show less'); + expect(component.$el.querySelector('.user-list-more .btn-link').innerText.trim()).toBe( + '- show less', + ); done(); }); }); @@ -264,16 +279,18 @@ describe('Assignee component', () => { }); it('shows "+1 more" label', () => { - expect(component.$el.querySelector('.user-list-more .btn-link').innerText.trim()) - .toBe('+ 1 more'); + expect(component.$el.querySelector('.user-list-more .btn-link').innerText.trim()).toBe( + '+ 1 more', + ); }); - it('shows "show less" label', (done) => { + it('shows "show less" label', done => { component.toggleShowLess(); Vue.nextTick(() => { - expect(component.$el.querySelector('.user-list-more .btn-link').innerText.trim()) - .toBe('- show less'); + expect(component.$el.querySelector('.user-list-more .btn-link').innerText.trim()).toBe( + '- show less', + ); done(); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js index 689580e6b91..6c7637eed13 100644 --- a/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js +++ b/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js @@ -69,12 +69,12 @@ describe('MRWidgetPipeline', () => { pipeline: mockData.pipeline, hasCi: true, ciStatus: null, - troubleshootingDocsPath: 'help', + troubleshootingDocsPath: 'help', }); - expect( - vm.$el.querySelector('.media-body').textContent.trim(), - ).toContain('Could not retrieve the pipeline status. For troubleshooting steps, read the <a href="help">documentation.</a>'); + expect(vm.$el.querySelector('.media-body').textContent.trim()).toContain( + 'Could not retrieve the pipeline status. For troubleshooting steps, read the <a href="help">documentation.</a>', + ); }); describe('with a pipeline', () => { @@ -88,34 +88,36 @@ describe('MRWidgetPipeline', () => { }); it('should render pipeline ID', () => { - expect( - vm.$el.querySelector('.pipeline-id').textContent.trim(), - ).toEqual(`#${mockData.pipeline.id}`); + expect(vm.$el.querySelector('.pipeline-id').textContent.trim()).toEqual( + `#${mockData.pipeline.id}`, + ); }); it('should render pipeline status and commit id', () => { - expect( - vm.$el.querySelector('.media-body').textContent.trim(), - ).toContain(mockData.pipeline.details.status.label); + expect(vm.$el.querySelector('.media-body').textContent.trim()).toContain( + mockData.pipeline.details.status.label, + ); - expect( - vm.$el.querySelector('.js-commit-link').textContent.trim(), - ).toEqual(mockData.pipeline.commit.short_id); + expect(vm.$el.querySelector('.js-commit-link').textContent.trim()).toEqual( + mockData.pipeline.commit.short_id, + ); - expect( - vm.$el.querySelector('.js-commit-link').getAttribute('href'), - ).toEqual(mockData.pipeline.commit.commit_path); + expect(vm.$el.querySelector('.js-commit-link').getAttribute('href')).toEqual( + mockData.pipeline.commit.commit_path, + ); }); it('should render pipeline graph', () => { expect(vm.$el.querySelector('.mr-widget-pipeline-graph')).toBeDefined(); - expect(vm.$el.querySelectorAll('.stage-container').length).toEqual(mockData.pipeline.details.stages.length); + expect(vm.$el.querySelectorAll('.stage-container').length).toEqual( + mockData.pipeline.details.stages.length, + ); }); it('should render coverage information', () => { - expect( - vm.$el.querySelector('.media-body').textContent, - ).toContain(`Coverage ${mockData.pipeline.coverage}`); + expect(vm.$el.querySelector('.media-body').textContent).toContain( + `Coverage ${mockData.pipeline.coverage}`, + ); }); }); @@ -133,30 +135,30 @@ describe('MRWidgetPipeline', () => { }); it('should render pipeline ID', () => { - expect( - vm.$el.querySelector('.pipeline-id').textContent.trim(), - ).toEqual(`#${mockData.pipeline.id}`); + expect(vm.$el.querySelector('.pipeline-id').textContent.trim()).toEqual( + `#${mockData.pipeline.id}`, + ); }); it('should render pipeline status', () => { - expect( - vm.$el.querySelector('.media-body').textContent.trim(), - ).toContain(mockData.pipeline.details.status.label); + expect(vm.$el.querySelector('.media-body').textContent.trim()).toContain( + mockData.pipeline.details.status.label, + ); - expect( - vm.$el.querySelector('.js-commit-link'), - ).toBeNull(); + expect(vm.$el.querySelector('.js-commit-link')).toBeNull(); }); it('should render pipeline graph', () => { expect(vm.$el.querySelector('.mr-widget-pipeline-graph')).toBeDefined(); - expect(vm.$el.querySelectorAll('.stage-container').length).toEqual(mockData.pipeline.details.stages.length); + expect(vm.$el.querySelectorAll('.stage-container').length).toEqual( + mockData.pipeline.details.stages.length, + ); }); it('should render coverage information', () => { - expect( - vm.$el.querySelector('.media-body').textContent, - ).toContain(`Coverage ${mockData.pipeline.coverage}`); + expect(vm.$el.querySelector('.media-body').textContent).toContain( + `Coverage ${mockData.pipeline.coverage}`, + ); }); }); @@ -172,9 +174,7 @@ describe('MRWidgetPipeline', () => { troubleshootingDocsPath: 'help', }); - expect( - vm.$el.querySelector('.media-body').textContent, - ).not.toContain('Coverage'); + expect(vm.$el.querySelector('.media-body').textContent).not.toContain('Coverage'); }); }); diff --git a/spec/javascripts/vue_mr_widget/mock_data.js b/spec/javascripts/vue_mr_widget/mock_data.js index c5e30a730cb..17554c4fe42 100644 --- a/spec/javascripts/vue_mr_widget/mock_data.js +++ b/spec/javascripts/vue_mr_widget/mock_data.js @@ -218,6 +218,7 @@ export default { diverged_commits_count: 0, only_allow_merge_if_pipeline_succeeds: false, commit_change_content_path: '/root/acets-app/merge_requests/22/commit_change_content', - merge_commit_path: 'http://localhost:3000/root/acets-app/commit/53027d060246c8f47e4a9310fb332aa52f221775', - troubleshooting_docs_path: 'help' + merge_commit_path: + 'http://localhost:3000/root/acets-app/commit/53027d060246c8f47e4a9310fb332aa52f221775', + troubleshooting_docs_path: 'help', }; diff --git a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js index 27b6c91e154..09fbe87b27e 100644 --- a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js +++ b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js @@ -454,7 +454,7 @@ describe('mrWidgetOptions', () => { deployed_at: '2017-03-22T22:44:42.258Z', deployed_at_formatted: 'Mar 22, 2017 10:44pm', changes, - status: 'success' + status: 'success', }; beforeEach(done => { @@ -607,33 +607,36 @@ describe('mrWidgetOptions', () => { describe('with post merge deployments', () => { beforeEach(done => { - vm.mr.postMergeDeployments = [{ - id: 15, - name: 'review/diplo', - url: '/root/acets-review-apps/environments/15', - stop_url: '/root/acets-review-apps/environments/15/stop', - metrics_url: '/root/acets-review-apps/environments/15/deployments/1/metrics', - metrics_monitoring_url: '/root/acets-review-apps/environments/15/metrics', - external_url: 'http://diplo.', - external_url_formatted: 'diplo.', - deployed_at: '2017-03-22T22:44:42.258Z', - deployed_at_formatted: 'Mar 22, 2017 10:44pm', - changes: [ - { - path: 'index.html', - external_url: 'http://root-master-patch-91341.volatile-watch.surge.sh/index.html', - }, - { - path: 'imgs/gallery.html', - external_url: 'http://root-master-patch-91341.volatile-watch.surge.sh/imgs/gallery.html', - }, - { - path: 'about/', - external_url: 'http://root-master-patch-91341.volatile-watch.surge.sh/about/', - }, - ], - status: 'success' - }]; + vm.mr.postMergeDeployments = [ + { + id: 15, + name: 'review/diplo', + url: '/root/acets-review-apps/environments/15', + stop_url: '/root/acets-review-apps/environments/15/stop', + metrics_url: '/root/acets-review-apps/environments/15/deployments/1/metrics', + metrics_monitoring_url: '/root/acets-review-apps/environments/15/metrics', + external_url: 'http://diplo.', + external_url_formatted: 'diplo.', + deployed_at: '2017-03-22T22:44:42.258Z', + deployed_at_formatted: 'Mar 22, 2017 10:44pm', + changes: [ + { + path: 'index.html', + external_url: 'http://root-master-patch-91341.volatile-watch.surge.sh/index.html', + }, + { + path: 'imgs/gallery.html', + external_url: + 'http://root-master-patch-91341.volatile-watch.surge.sh/imgs/gallery.html', + }, + { + path: 'about/', + external_url: 'http://root-master-patch-91341.volatile-watch.surge.sh/about/', + }, + ], + status: 'success', + }, + ]; vm.$nextTick(done); }); diff --git a/spec/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker_spec.js b/spec/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker_spec.js index 3483b7d387d..c507a97d37e 100644 --- a/spec/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker_spec.js @@ -12,7 +12,7 @@ describe('collapsedGroupedDatePicker', () => { }); describe('toggleCollapse events', () => { - beforeEach((done) => { + beforeEach(done => { spyOn(vm, 'toggleSidebar'); vm.minDate = new Date('07/17/2016'); Vue.nextTick(done); @@ -26,7 +26,7 @@ describe('collapsedGroupedDatePicker', () => { }); describe('minDate and maxDate', () => { - beforeEach((done) => { + beforeEach(done => { vm.minDate = new Date('07/17/2016'); vm.maxDate = new Date('07/17/2017'); Vue.nextTick(done); @@ -42,7 +42,7 @@ describe('collapsedGroupedDatePicker', () => { }); describe('minDate', () => { - beforeEach((done) => { + beforeEach(done => { vm.minDate = new Date('07/17/2016'); Vue.nextTick(done); }); @@ -56,7 +56,7 @@ describe('collapsedGroupedDatePicker', () => { }); describe('maxDate', () => { - beforeEach((done) => { + beforeEach(done => { vm.maxDate = new Date('07/17/2017'); Vue.nextTick(done); }); diff --git a/spec/javascripts/vue_shared/components/sidebar/date_picker_spec.js b/spec/javascripts/vue_shared/components/sidebar/date_picker_spec.js index 1581f4e3eb1..805ba7b9947 100644 --- a/spec/javascripts/vue_shared/components/sidebar/date_picker_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/date_picker_spec.js @@ -41,7 +41,7 @@ describe('sidebarDatePicker', () => { expect(vm.$el.querySelector('.value-content span').innerText.trim()).toEqual('None'); }); - it('should render date-picker when editing', (done) => { + it('should render date-picker when editing', done => { vm.editing = true; Vue.nextTick(() => { expect(vm.$el.querySelector('.pika-label')).toBeDefined(); @@ -50,7 +50,7 @@ describe('sidebarDatePicker', () => { }); describe('editable', () => { - beforeEach((done) => { + beforeEach(done => { vm.editable = true; Vue.nextTick(done); }); @@ -59,7 +59,7 @@ describe('sidebarDatePicker', () => { expect(vm.$el.querySelector('.title .btn-blank').innerText.trim()).toEqual('Edit'); }); - it('should enable editing when edit button is clicked', (done) => { + it('should enable editing when edit button is clicked', done => { vm.isLoading = false; Vue.nextTick(() => { vm.$el.querySelector('.title .btn-blank').click(); @@ -70,7 +70,7 @@ describe('sidebarDatePicker', () => { }); }); - it('should render date if selectedDate', (done) => { + it('should render date if selectedDate', done => { vm.selectedDate = new Date('07/07/2017'); Vue.nextTick(() => { expect(vm.$el.querySelector('.value-content strong').innerText.trim()).toEqual('Jul 7, 2017'); @@ -79,7 +79,7 @@ describe('sidebarDatePicker', () => { }); describe('selectedDate and editable', () => { - beforeEach((done) => { + beforeEach(done => { vm.selectedDate = new Date('07/07/2017'); vm.editable = true; Vue.nextTick(done); @@ -100,7 +100,7 @@ describe('sidebarDatePicker', () => { }); describe('showToggleSidebar', () => { - beforeEach((done) => { + beforeEach(done => { vm.showToggleSidebar = true; Vue.nextTick(done); }); diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js index 9a691116cf8..804b33422bd 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js @@ -49,7 +49,9 @@ describe('DropdownValueCollapsedComponent', () => { const vmMoreLabels = createComponent(mockMoreLabels); - expect(vmMoreLabels.labelsList).toBe('Foo Label, Foo Label, Foo Label, Foo Label, Foo Label, and 2 more'); + expect(vmMoreLabels.labelsList).toBe( + 'Foo Label, Foo Label, Foo Label, Foo Label, Foo Label, and 2 more', + ); vmMoreLabels.$destroy(); }); |