diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index 83aba188d2b..55a8f64f5a4 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -216,7 +216,6 @@ linters: - "app/views/projects/mattermosts/_team_selection.html.haml" - "app/views/projects/mattermosts/new.html.haml" - "app/views/projects/merge_requests/_commits.html.haml" - - "app/views/projects/merge_requests/_discussion.html.haml" - "app/views/projects/merge_requests/_how_to_merge.html.haml" - "app/views/projects/merge_requests/_mr_title.html.haml" - "app/views/projects/merge_requests/conflicts/_commit_stats.html.haml" diff --git a/app/assets/javascripts/diff_notes/components/comment_resolve_btn.js b/app/assets/javascripts/diff_notes/components/comment_resolve_btn.js deleted file mode 100644 index dd60e2c7684..00000000000 --- a/app/assets/javascripts/diff_notes/components/comment_resolve_btn.js +++ /dev/null @@ -1,65 +0,0 @@ -/* global CommentsStore */ - -import $ from 'jquery'; -import Vue from 'vue'; -import { __ } from '~/locale'; - -const CommentAndResolveBtn = Vue.extend({ - props: { - discussionId: { - type: String, - required: true, - }, - }, - data() { - return { - textareaIsEmpty: true, - discussion: {}, - }; - }, - computed: { - showButton() { - if (this.discussion) { - return this.discussion.isResolvable(); - } - return false; - }, - isDiscussionResolved() { - return this.discussion.isResolved(); - }, - buttonText() { - if (this.textareaIsEmpty) { - return this.isDiscussionResolved ? __('Unresolve thread') : __('Resolve thread'); - } - return this.isDiscussionResolved - ? __('Comment & unresolve thread') - : __('Comment & resolve thread'); - }, - }, - created() { - if (this.discussionId) { - this.discussion = CommentsStore.state[this.discussionId]; - } - }, - mounted() { - if (!this.discussionId) return; - - const $textarea = $( - `.js-discussion-note-form[data-discussion-id=${this.discussionId}] .note-textarea`, - ); - this.textareaIsEmpty = $textarea.val() === ''; - - $textarea.on('input.comment-and-resolve-btn', () => { - this.textareaIsEmpty = $textarea.val() === ''; - }); - }, - destroyed() { - if (!this.discussionId) return; - - $(`.js-discussion-note-form[data-discussion-id=${this.discussionId}] .note-textarea`).off( - 'input.comment-and-resolve-btn', - ); - }, -}); - -Vue.component('comment-and-resolve-btn', CommentAndResolveBtn); diff --git a/app/assets/javascripts/diff_notes/components/diff_note_avatars.js b/app/assets/javascripts/diff_notes/components/diff_note_avatars.js deleted file mode 100644 index b5a781cbc92..00000000000 --- a/app/assets/javascripts/diff_notes/components/diff_note_avatars.js +++ /dev/null @@ -1,189 +0,0 @@ -/* global CommentsStore */ - -import $ from 'jquery'; -import Vue from 'vue'; -import collapseIcon from '../icons/collapse_icon.svg'; -import Notes from '../../notes'; -import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue'; -import { n__ } from '~/locale'; - -const DiffNoteAvatars = Vue.extend({ - components: { - userAvatarImage, - }, - props: { - discussionId: { - type: String, - required: true, - }, - }, - data() { - return { - isVisible: false, - lineType: '', - storeState: CommentsStore.state, - shownAvatars: 3, - collapseIcon, - }; - }, - computed: { - discussionClassName() { - return `js-diff-avatars-${this.discussionId}`; - }, - notesSubset() { - let notes = []; - - if (this.discussion) { - notes = Object.keys(this.discussion.notes) - .slice(0, this.shownAvatars) - .map(noteId => this.discussion.notes[noteId]); - } - - return notes; - }, - extraNotesTitle() { - if (this.discussion) { - const extra = this.discussion.notesCount() - this.shownAvatars; - - return n__('%d more comment', '%d more comments', extra); - } - - return ''; - }, - discussion() { - return this.storeState[this.discussionId]; - }, - notesCount() { - if (this.discussion) { - return this.discussion.notesCount(); - } - - return 0; - }, - moreText() { - const plusSign = this.notesCount < 100 ? '+' : ''; - - return `${plusSign}${this.notesCount - this.shownAvatars}`; - }, - }, - watch: { - storeState: { - handler() { - this.$nextTick(() => { - $('.has-tooltip', this.$el).tooltip('_fixTitle'); - - // We need to add/remove a class to an element that is outside the Vue instance - this.addNoCommentClass(); - }); - }, - deep: true, - }, - }, - mounted() { - this.$nextTick(() => { - this.addNoCommentClass(); - this.setDiscussionVisible(); - - this.lineType = $(this.$el) - .closest('.diff-line-num') - .hasClass('old_line') - ? 'old' - : 'new'; - }); - - $(document).on('toggle.comments', () => { - this.$nextTick(() => { - this.setDiscussionVisible(); - }); - }); - }, - beforeDestroy() { - this.addNoCommentClass(); - $(document).off('toggle.comments'); - }, - methods: { - clickedAvatar(e) { - Notes.instance.onAddDiffNote(e); - - // Toggle the active state of the toggle all button - this.toggleDiscussionsToggleState(); - - this.$nextTick(() => { - this.setDiscussionVisible(); - - $('.has-tooltip', this.$el).tooltip('_fixTitle'); - $('.has-tooltip', this.$el).tooltip('hide'); - }); - }, - addNoCommentClass() { - const { notesCount } = this; - - $(this.$el) - .closest('.js-avatar-container') - .toggleClass('no-comment-btn', notesCount > 0) - .nextUntil('.js-avatar-container') - .toggleClass('no-comment-btn', notesCount > 0); - }, - toggleDiscussionsToggleState() { - const $notesHolders = $(this.$el) - .closest('.code') - .find('.notes_holder'); - const $visibleNotesHolders = $notesHolders.filter(':visible'); - const $toggleDiffCommentsBtn = $(this.$el) - .closest('.diff-file') - .find('.js-toggle-diff-comments'); - - $toggleDiffCommentsBtn.toggleClass( - 'active', - $notesHolders.length === $visibleNotesHolders.length, - ); - }, - setDiscussionVisible() { - this.isVisible = $(`.diffs .notes[data-discussion-id="${this.discussion.id}"]`).is( - ':visible', - ); - }, - getTooltipText(note) { - return `${note.authorName}: ${note.noteTruncated}`; - }, - }, - template: ` -
-
- - - {{ moreText }} -
- -
- `, -}); - -Vue.component('diff-note-avatars', DiffNoteAvatars); diff --git a/app/assets/javascripts/diff_notes/components/jump_to_discussion.js b/app/assets/javascripts/diff_notes/components/jump_to_discussion.js deleted file mode 100644 index 1de00c9f08b..00000000000 --- a/app/assets/javascripts/diff_notes/components/jump_to_discussion.js +++ /dev/null @@ -1,210 +0,0 @@ -/* eslint-disable func-names, no-continue */ -/* global CommentsStore */ - -import $ from 'jquery'; -import 'vendor/jquery.scrollTo'; -import Vue from 'vue'; -import { __ } from '~/locale'; - -import DiscussionMixins from '../mixins/discussion'; - -const JumpToDiscussion = Vue.extend({ - mixins: [DiscussionMixins], - props: { - discussionId: { - type: String, - required: true, - }, - }, - data() { - return { - discussions: CommentsStore.state, - discussion: {}, - }; - }, - computed: { - buttonText() { - if (this.discussionId) { - return __('Jump to next unresolved thread'); - } - return __('Jump to first unresolved thread'); - }, - allResolved() { - return this.unresolvedDiscussionCount === 0; - }, - showButton() { - if (this.discussionId) { - if (this.unresolvedDiscussionCount > 1) { - return true; - } - return this.discussionId !== this.lastResolvedId; - } - return this.unresolvedDiscussionCount >= 1; - }, - lastResolvedId() { - let lastId; - Object.keys(this.discussions).forEach(discussionId => { - const discussion = this.discussions[discussionId]; - - if (!discussion.isResolved()) { - lastId = discussion.id; - } - }); - return lastId; - }, - }, - created() { - this.discussion = this.discussions[this.discussionId]; - }, - methods: { - jumpToNextUnresolvedDiscussion() { - let discussionsSelector; - let discussionIdsInScope; - let firstUnresolvedDiscussionId; - let nextUnresolvedDiscussionId; - let activeTab = window.mrTabs.currentAction; - let hasDiscussionsToJumpTo = true; - let jumpToFirstDiscussion = !this.discussionId; - - const discussionIdsForElements = function(elements) { - return elements - .map(function() { - return $(this).attr('data-discussion-id'); - }) - .toArray(); - }; - - const { discussions } = this; - - if (activeTab === 'diffs') { - discussionsSelector = '.diffs .notes[data-discussion-id]'; - discussionIdsInScope = discussionIdsForElements($(discussionsSelector)); - - let unresolvedDiscussionCount = 0; - - for (let i = 0; i < discussionIdsInScope.length; i += 1) { - const discussionId = discussionIdsInScope[i]; - const discussion = discussions[discussionId]; - if (discussion && !discussion.isResolved()) { - unresolvedDiscussionCount += 1; - } - } - - if (this.discussionId && !this.discussion.isResolved()) { - // If this is the last unresolved discussion on the diffs tab, - // there are no discussions to jump to. - if (unresolvedDiscussionCount === 1) { - hasDiscussionsToJumpTo = false; - } - } else if (unresolvedDiscussionCount === 0) { - // If there are no unresolved discussions on the diffs tab at all, - // there are no discussions to jump to. - hasDiscussionsToJumpTo = false; - } - } else if (activeTab !== 'show') { - // If we are on the commits or builds tabs, - // there are no discussions to jump to. - hasDiscussionsToJumpTo = false; - } - - if (!hasDiscussionsToJumpTo) { - // If there are no discussions to jump to on the current page, - // switch to the notes tab and jump to the first discussion there. - window.mrTabs.activateTab('show'); - activeTab = 'show'; - jumpToFirstDiscussion = true; - } - - if (activeTab === 'show') { - discussionsSelector = '.discussion[data-discussion-id]'; - discussionIdsInScope = discussionIdsForElements($(discussionsSelector)); - } - - let currentDiscussionFound = false; - for (let i = 0; i < discussionIdsInScope.length; i += 1) { - const discussionId = discussionIdsInScope[i]; - const discussion = discussions[discussionId]; - - if (!discussion) { - // Discussions for comments on commits in this MR don't have a resolved status. - continue; - } - - if (!firstUnresolvedDiscussionId && !discussion.isResolved()) { - firstUnresolvedDiscussionId = discussionId; - - if (jumpToFirstDiscussion) { - break; - } - } - - if (!jumpToFirstDiscussion) { - if (currentDiscussionFound) { - if (!discussion.isResolved()) { - nextUnresolvedDiscussionId = discussionId; - break; - } else { - continue; - } - } - - if (discussionId === this.discussionId) { - currentDiscussionFound = true; - } - } - } - - nextUnresolvedDiscussionId = nextUnresolvedDiscussionId || firstUnresolvedDiscussionId; - - if (!nextUnresolvedDiscussionId) { - return; - } - - let $target = $(`${discussionsSelector}[data-discussion-id="${nextUnresolvedDiscussionId}"]`); - - if (activeTab === 'show') { - $target = $target.closest('.note-discussion'); - - // If the next discussion is closed, toggle it open. - if ($target.find('.js-toggle-content').is(':hidden')) { - $target.find('.js-toggle-button i').trigger('click'); - } - } else if (activeTab === 'diffs') { - // Resolved discussions are hidden in the diffs tab by default. - // If they are marked unresolved on the notes tab, they will still be hidden on the diffs tab. - // When jumping between unresolved discussions on the diffs tab, we show them. - $target.closest('.content').show(); - - const $notesHolder = $target.closest('tr.notes_holder'); - - // Image diff discussions does not use notes_holder - // so we should keep original $target value in those cases - if ($notesHolder.length > 0) { - $target = $notesHolder; - } - - $target.show(); - - // If we are on the diffs tab, we don't scroll to the discussion itself, but to - // 4 diff lines above it: the line the discussion was in response to + 3 context - let prevEl; - for (let i = 0; i < 4; i += 1) { - prevEl = $target.prev(); - - // If the discussion doesn't have 4 lines above it, we'll have to do with fewer. - if (!prevEl.hasClass('line_holder')) { - break; - } - - $target = prevEl; - } - } - - $.scrollTo($target, { - offset: -150, - }); - }, - }, -}); - -Vue.component('jump-to-discussion', JumpToDiscussion); diff --git a/app/assets/javascripts/diff_notes/components/new_issue_for_discussion.js b/app/assets/javascripts/diff_notes/components/new_issue_for_discussion.js deleted file mode 100644 index e0c09aa0eee..00000000000 --- a/app/assets/javascripts/diff_notes/components/new_issue_for_discussion.js +++ /dev/null @@ -1,28 +0,0 @@ -/* global CommentsStore */ - -import Vue from 'vue'; - -const NewIssueForDiscussion = Vue.extend({ - props: { - discussionId: { - type: String, - required: true, - }, - }, - data() { - return { - discussions: CommentsStore.state, - }; - }, - computed: { - discussion() { - return this.discussions[this.discussionId]; - }, - showButton() { - if (this.discussion) return !this.discussion.isResolved(); - return false; - }, - }, -}); - -Vue.component('new-issue-for-discussion-btn', NewIssueForDiscussion); diff --git a/app/assets/javascripts/diff_notes/components/resolve_btn.js b/app/assets/javascripts/diff_notes/components/resolve_btn.js deleted file mode 100644 index 0943712d0c5..00000000000 --- a/app/assets/javascripts/diff_notes/components/resolve_btn.js +++ /dev/null @@ -1,145 +0,0 @@ -/* global CommentsStore */ -/* global ResolveService */ - -import $ from 'jquery'; -import Vue from 'vue'; -import { deprecatedCreateFlash as Flash } from '../../flash'; -import { sprintf, __ } from '~/locale'; - -const ResolveBtn = Vue.extend({ - props: { - noteId: { - type: Number, - required: true, - }, - discussionId: { - type: String, - required: true, - }, - resolved: { - type: Boolean, - required: true, - }, - canResolve: { - type: Boolean, - required: true, - }, - resolvedBy: { - type: String, - required: true, - }, - authorName: { - type: String, - required: true, - }, - authorAvatar: { - type: String, - required: true, - }, - noteTruncated: { - type: String, - required: true, - }, - }, - data() { - return { - discussions: CommentsStore.state, - loading: false, - }; - }, - computed: { - discussion() { - return this.discussions[this.discussionId]; - }, - note() { - return this.discussion ? this.discussion.getNote(this.noteId) : {}; - }, - buttonText() { - if (this.isResolved) { - return sprintf(__('Resolved by %{resolvedByName}'), { - resolvedByName: this.resolvedByName, - }); - } else if (this.canResolve) { - return __('Mark as resolved'); - } - - return __('Unable to resolve'); - }, - isResolved() { - if (this.note) { - return this.note.resolved; - } - - return false; - }, - resolvedByName() { - return this.note.resolved_by; - }, - }, - watch: { - discussions: { - handler: 'updateTooltip', - deep: true, - }, - }, - mounted() { - $(this.$refs.button).tooltip({ - container: 'body', - }); - }, - beforeDestroy() { - CommentsStore.delete(this.discussionId, this.noteId); - }, - created() { - CommentsStore.create({ - discussionId: this.discussionId, - noteId: this.noteId, - canResolve: this.canResolve, - resolved: this.resolved, - resolvedBy: this.resolvedBy, - authorName: this.authorName, - authorAvatar: this.authorAvatar, - noteTruncated: this.noteTruncated, - }); - }, - methods: { - updateTooltip() { - this.$nextTick(() => { - $(this.$refs.button) - .tooltip('hide') - .tooltip('_fixTitle'); - }); - }, - resolve() { - if (!this.canResolve) return; - - let promise; - this.loading = true; - - if (this.isResolved) { - promise = ResolveService.unresolve(this.noteId); - } else { - promise = ResolveService.resolve(this.noteId); - } - - promise - .then(resp => resp.json()) - .then(data => { - this.loading = false; - - const resolvedBy = data ? data.resolved_by : null; - - CommentsStore.update(this.discussionId, this.noteId, !this.isResolved, resolvedBy); - this.discussion.updateHeadline(data); - gl.mrWidget.checkStatus(); - this.updateTooltip(); - }) - .catch( - () => - new Flash(__('An error occurred when trying to resolve a comment. Please try again.')), - ); - }, - }, -}); - -Vue.component('resolve-btn', ResolveBtn); diff --git a/app/assets/javascripts/diff_notes/components/resolve_count.js b/app/assets/javascripts/diff_notes/components/resolve_count.js deleted file mode 100644 index f960853b25b..00000000000 --- a/app/assets/javascripts/diff_notes/components/resolve_count.js +++ /dev/null @@ -1,28 +0,0 @@ -/* global CommentsStore */ - -import Vue from 'vue'; - -import DiscussionMixins from '../mixins/discussion'; - -window.ResolveCount = Vue.extend({ - mixins: [DiscussionMixins], - props: { - loggedOut: { - type: Boolean, - required: true, - }, - }, - data() { - return { - discussions: CommentsStore.state, - }; - }, - computed: { - allResolved() { - return this.resolvedDiscussionCount === this.discussionCount; - }, - resolvedCountText() { - return this.discussionCount === 1 ? 'discussion' : 'discussions'; - }, - }, -}); diff --git a/app/assets/javascripts/diff_notes/diff_notes_bundle.js b/app/assets/javascripts/diff_notes/diff_notes_bundle.js deleted file mode 100644 index 92862d4c933..00000000000 --- a/app/assets/javascripts/diff_notes/diff_notes_bundle.js +++ /dev/null @@ -1,72 +0,0 @@ -/* eslint-disable func-names, new-cap */ - -import $ from 'jquery'; -import Vue from 'vue'; -import './models/discussion'; -import './models/note'; -import './stores/comments'; -import './services/resolve'; -import './mixins/discussion'; -import './components/comment_resolve_btn'; -import './components/jump_to_discussion'; -import './components/resolve_btn'; -import './components/resolve_count'; -import './components/diff_note_avatars'; -import './components/new_issue_for_discussion'; - -export default () => { - const projectPathHolder = - document.querySelector('.merge-request') || document.querySelector('.commit-box'); - const { projectPath } = projectPathHolder.dataset; - const COMPONENT_SELECTOR = - 'resolve-btn, jump-to-discussion, comment-and-resolve-btn, new-issue-for-discussion-btn'; - - window.gl = window.gl || {}; - window.gl.diffNoteApps = {}; - - window.ResolveService = new gl.DiffNotesResolveServiceClass(projectPath); - - gl.diffNotesCompileComponents = () => { - $('diff-note-avatars').each(function() { - const tmp = Vue.extend({ - template: $(this).get(0).outerHTML, - }); - const tmpApp = new tmp().$mount(); - - $(this).replaceWith(tmpApp.$el); - $(tmpApp.$el).one('remove.vue', () => { - tmpApp.$destroy(); - tmpApp.$el.remove(); - }); - }); - - const $components = $(COMPONENT_SELECTOR).filter(function() { - return $(this).closest('resolve-count').length !== 1; - }); - - if ($components) { - $components.each(function() { - const $this = $(this); - const noteId = $this.attr(':note-id'); - const discussionId = $this.attr(':discussion-id'); - - if ($this.is('comment-and-resolve-btn') && !discussionId) return; - - const tmp = Vue.extend({ - template: $this.get(0).outerHTML, - }); - const tmpApp = new tmp().$mount(); - - if (noteId) { - gl.diffNoteApps[`note_${noteId}`] = tmpApp; - } - - $this.replaceWith(tmpApp.$el); - }); - } - }; - - gl.diffNotesCompileComponents(); - - $(window).trigger('resize.nav'); -}; diff --git a/app/assets/javascripts/diff_notes/icons/collapse_icon.svg b/app/assets/javascripts/diff_notes/icons/collapse_icon.svg deleted file mode 100644 index bd4b393cfaa..00000000000 --- a/app/assets/javascripts/diff_notes/icons/collapse_icon.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/app/assets/javascripts/diff_notes/mixins/discussion.js b/app/assets/javascripts/diff_notes/mixins/discussion.js deleted file mode 100644 index ef3001393cf..00000000000 --- a/app/assets/javascripts/diff_notes/mixins/discussion.js +++ /dev/null @@ -1,37 +0,0 @@ -/* eslint-disable guard-for-in, no-restricted-syntax, */ - -const DiscussionMixins = { - computed: { - discussionCount() { - return Object.keys(this.discussions).length; - }, - resolvedDiscussionCount() { - let resolvedCount = 0; - - for (const discussionId in this.discussions) { - const discussion = this.discussions[discussionId]; - - if (discussion.isResolved()) { - resolvedCount += 1; - } - } - - return resolvedCount; - }, - unresolvedDiscussionCount() { - let unresolvedCount = 0; - - for (const discussionId in this.discussions) { - const discussion = this.discussions[discussionId]; - - if (!discussion.isResolved()) { - unresolvedCount += 1; - } - } - - return unresolvedCount; - }, - }, -}; - -export default DiscussionMixins; diff --git a/app/assets/javascripts/diff_notes/models/discussion.js b/app/assets/javascripts/diff_notes/models/discussion.js deleted file mode 100644 index 97296a40d6e..00000000000 --- a/app/assets/javascripts/diff_notes/models/discussion.js +++ /dev/null @@ -1,99 +0,0 @@ -/* eslint-disable guard-for-in, no-restricted-syntax */ -/* global NoteModel */ - -import $ from 'jquery'; -import Vue from 'vue'; -import { localTimeAgo } from '../../lib/utils/datetime_utility'; - -class DiscussionModel { - constructor(discussionId) { - this.id = discussionId; - this.notes = {}; - this.loading = false; - this.canResolve = false; - } - - createNote(noteObj) { - Vue.set(this.notes, noteObj.noteId, new NoteModel(this.id, noteObj)); - } - - deleteNote(noteId) { - Vue.delete(this.notes, noteId); - } - - getNote(noteId) { - return this.notes[noteId]; - } - - notesCount() { - return Object.keys(this.notes).length; - } - - isResolved() { - for (const noteId in this.notes) { - const note = this.notes[noteId]; - - if (!note.resolved) { - return false; - } - } - return true; - } - - resolveAllNotes(resolvedBy) { - for (const noteId in this.notes) { - const note = this.notes[noteId]; - - if (!note.resolved) { - note.resolved = true; - note.resolved_by = resolvedBy; - } - } - } - - unResolveAllNotes() { - for (const noteId in this.notes) { - const note = this.notes[noteId]; - - if (note.resolved) { - note.resolved = false; - note.resolved_by = null; - } - } - } - - updateHeadline(data) { - const discussionSelector = `.discussion[data-discussion-id="${this.id}"]`; - const $discussionHeadline = $(`${discussionSelector} .js-discussion-headline`); - - if (data.discussion_headline_html) { - if ($discussionHeadline.length) { - $discussionHeadline.replaceWith(data.discussion_headline_html); - } else { - $(`${discussionSelector} .discussion-header`).append(data.discussion_headline_html); - } - - localTimeAgo($('.js-timeago', `${discussionSelector}`)); - } else { - $discussionHeadline.remove(); - } - } - - isResolvable() { - if (!this.canResolve) { - return false; - } - - for (const noteId in this.notes) { - const note = this.notes[noteId]; - - if (note.canResolve) { - return true; - } - } - - return false; - } -} - -window.DiscussionModel = DiscussionModel; diff --git a/app/assets/javascripts/diff_notes/models/note.js b/app/assets/javascripts/diff_notes/models/note.js deleted file mode 100644 index 825a69deeec..00000000000 --- a/app/assets/javascripts/diff_notes/models/note.js +++ /dev/null @@ -1,14 +0,0 @@ -class NoteModel { - constructor(discussionId, noteObj) { - this.discussionId = discussionId; - this.id = noteObj.noteId; - this.canResolve = noteObj.canResolve; - this.resolved = noteObj.resolved; - this.resolved_by = noteObj.resolvedBy; - this.authorName = noteObj.authorName; - this.authorAvatar = noteObj.authorAvatar; - this.noteTruncated = noteObj.noteTruncated; - } -} - -window.NoteModel = NoteModel; diff --git a/app/assets/javascripts/diff_notes/services/resolve.js b/app/assets/javascripts/diff_notes/services/resolve.js deleted file mode 100644 index d6975963977..00000000000 --- a/app/assets/javascripts/diff_notes/services/resolve.js +++ /dev/null @@ -1,86 +0,0 @@ -/* global CommentsStore */ - -import Vue from 'vue'; -import { deprecatedCreateFlash as Flash } from '../../flash'; -import { __ } from '~/locale'; - -window.gl = window.gl || {}; - -class ResolveServiceClass { - constructor(root) { - this.noteResource = Vue.resource(`${root}/notes{/noteId}/resolve?html=true`); - this.discussionResource = Vue.resource( - `${root}/merge_requests{/mergeRequestId}/discussions{/discussionId}/resolve?html=true`, - ); - } - - resolve(noteId) { - return this.noteResource.save({ noteId }, {}); - } - - unresolve(noteId) { - return this.noteResource.delete({ noteId }, {}); - } - - toggleResolveForDiscussion(mergeRequestId, discussionId) { - const discussion = CommentsStore.state[discussionId]; - const isResolved = discussion.isResolved(); - let promise; - - if (isResolved) { - promise = this.unResolveAll(mergeRequestId, discussionId); - } else { - promise = this.resolveAll(mergeRequestId, discussionId); - } - - promise - .then(resp => resp.json()) - .then(data => { - discussion.loading = false; - const resolvedBy = data ? data.resolved_by : null; - - if (isResolved) { - discussion.unResolveAllNotes(); - } else { - discussion.resolveAllNotes(resolvedBy); - } - - if (gl.mrWidget) gl.mrWidget.checkStatus(); - discussion.updateHeadline(data); - }) - .catch( - () => - new Flash(__('An error occurred when trying to resolve a discussion. Please try again.')), - ); - } - - resolveAll(mergeRequestId, discussionId) { - const discussion = CommentsStore.state[discussionId]; - - discussion.loading = true; - - return this.discussionResource.save( - { - mergeRequestId, - discussionId, - }, - {}, - ); - } - - unResolveAll(mergeRequestId, discussionId) { - const discussion = CommentsStore.state[discussionId]; - - discussion.loading = true; - - return this.discussionResource.delete( - { - mergeRequestId, - discussionId, - }, - {}, - ); - } -} - -gl.DiffNotesResolveServiceClass = ResolveServiceClass; diff --git a/app/assets/javascripts/diff_notes/stores/comments.js b/app/assets/javascripts/diff_notes/stores/comments.js deleted file mode 100644 index 9bde18c4edf..00000000000 --- a/app/assets/javascripts/diff_notes/stores/comments.js +++ /dev/null @@ -1,56 +0,0 @@ -/* eslint-disable no-restricted-syntax, guard-for-in */ -/* global DiscussionModel */ - -import Vue from 'vue'; - -window.CommentsStore = { - state: {}, - get(discussionId, noteId) { - return this.state[discussionId].getNote(noteId); - }, - createDiscussion(discussionId, canResolve) { - let discussion = this.state[discussionId]; - if (!this.state[discussionId]) { - discussion = new DiscussionModel(discussionId); - Vue.set(this.state, discussionId, discussion); - } - - if (canResolve !== undefined) { - discussion.canResolve = canResolve; - } - - return discussion; - }, - create(noteObj) { - const discussion = this.createDiscussion(noteObj.discussionId); - - discussion.createNote(noteObj); - }, - update(discussionId, noteId, resolved, resolvedBy) { - const discussion = this.state[discussionId]; - const note = discussion.getNote(noteId); - note.resolved = resolved; - note.resolved_by = resolvedBy; - }, - delete(discussionId, noteId) { - const discussion = this.state[discussionId]; - discussion.deleteNote(noteId); - - if (discussion.notesCount() === 0) { - Vue.delete(this.state, discussionId); - } - }, - unresolvedDiscussionIds() { - const ids = []; - - for (const discussionId in this.state) { - const discussion = this.state[discussionId]; - - if (!discussion.isResolved()) { - ids.push(discussion.id); - } - } - - return ids; - }, -}; diff --git a/app/assets/javascripts/diffs/components/diff_file.vue b/app/assets/javascripts/diffs/components/diff_file.vue index 091704c49f7..02396a4ba1b 100644 --- a/app/assets/javascripts/diffs/components/diff_file.vue +++ b/app/assets/javascripts/diffs/components/diff_file.vue @@ -1,32 +1,26 @@ + + diff --git a/app/assets/javascripts/integrations/edit/components/integration_form.vue b/app/assets/javascripts/integrations/edit/components/integration_form.vue index 0460ed6791e..0fd39c5635d 100644 --- a/app/assets/javascripts/integrations/edit/components/integration_form.vue +++ b/app/assets/javascripts/integrations/edit/components/integration_form.vue @@ -1,8 +1,9 @@