Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-08-20 21:42:06 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-08-20 21:42:06 +0300
commit6e4e1050d9dba2b7b2523fdd1768823ab85feef4 (patch)
tree78be5963ec075d80116a932011d695dd33910b4e /app/assets/javascripts/notes
parent1ce776de4ae122aba3f349c02c17cebeaa8ecf07 (diff)
Add latest changes from gitlab-org/gitlab@13-3-stable-ee
Diffstat (limited to 'app/assets/javascripts/notes')
-rw-r--r--app/assets/javascripts/notes/components/comment_form.vue2
-rw-r--r--app/assets/javascripts/notes/components/discussion_actions.vue11
-rw-r--r--app/assets/javascripts/notes/components/discussion_filter_note.vue12
-rw-r--r--app/assets/javascripts/notes/components/discussion_navigator.vue (renamed from app/assets/javascripts/notes/components/discussion_keyboard_navigator.vue)6
-rw-r--r--app/assets/javascripts/notes/components/discussion_notes.vue18
-rw-r--r--app/assets/javascripts/notes/components/discussion_resolve_with_issue_button.vue13
-rw-r--r--app/assets/javascripts/notes/components/note_actions.vue4
-rw-r--r--app/assets/javascripts/notes/components/note_awards_list.vue2
-rw-r--r--app/assets/javascripts/notes/components/note_header.vue2
-rw-r--r--app/assets/javascripts/notes/components/noteable_discussion.vue7
-rw-r--r--app/assets/javascripts/notes/components/noteable_note.vue58
-rw-r--r--app/assets/javascripts/notes/components/notes_app.vue6
-rw-r--r--app/assets/javascripts/notes/event_hub.js4
-rw-r--r--app/assets/javascripts/notes/index.js5
-rw-r--r--app/assets/javascripts/notes/mixins/diff_line_note_form.js2
-rw-r--r--app/assets/javascripts/notes/mixins/discussion_navigation.js10
-rw-r--r--app/assets/javascripts/notes/mixins/resolvable.js2
-rw-r--r--app/assets/javascripts/notes/stores/actions.js54
-rw-r--r--app/assets/javascripts/notes/stores/getters.js7
-rw-r--r--app/assets/javascripts/notes/stores/mutation_types.js2
-rw-r--r--app/assets/javascripts/notes/stores/mutations.js9
21 files changed, 161 insertions, 75 deletions
diff --git a/app/assets/javascripts/notes/components/comment_form.vue b/app/assets/javascripts/notes/components/comment_form.vue
index ac93d3df654..7cfff98e9f7 100644
--- a/app/assets/javascripts/notes/components/comment_form.vue
+++ b/app/assets/javascripts/notes/components/comment_form.vue
@@ -6,7 +6,7 @@ import Autosize from 'autosize';
import { GlAlert, GlIntersperse, GlLink, GlSprintf } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
-import Flash from '../../flash';
+import { deprecatedCreateFlash as Flash } from '../../flash';
import Autosave from '../../autosave';
import {
capitalizeFirstCharacter,
diff --git a/app/assets/javascripts/notes/components/discussion_actions.vue b/app/assets/javascripts/notes/components/discussion_actions.vue
index 251199f1778..878a748e99a 100644
--- a/app/assets/javascripts/notes/components/discussion_actions.vue
+++ b/app/assets/javascripts/notes/components/discussion_actions.vue
@@ -3,6 +3,7 @@ import ReplyPlaceholder from './discussion_reply_placeholder.vue';
import ResolveDiscussionButton from './discussion_resolve_button.vue';
import ResolveWithIssueButton from './discussion_resolve_with_issue_button.vue';
import JumpToNextDiscussionButton from './discussion_jump_to_next_button.vue';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
export default {
name: 'DiscussionActions',
@@ -12,6 +13,7 @@ export default {
ResolveWithIssueButton,
JumpToNextDiscussionButton,
},
+ mixins: [glFeatureFlagsMixin()],
props: {
discussion: {
type: Object,
@@ -36,6 +38,9 @@ export default {
},
},
computed: {
+ hideJumpToNextUnresolvedInThreads() {
+ return this.glFeatures.hideJumpToNextUnresolvedInThreads;
+ },
resolvableNotes() {
return this.discussion.notes.filter(x => x.resolvable);
},
@@ -70,7 +75,11 @@ export default {
/>
</div>
<div
- v-if="discussion.resolvable && shouldShowJumpToNextDiscussion"
+ v-if="
+ !hideJumpToNextUnresolvedInThreads &&
+ discussion.resolvable &&
+ shouldShowJumpToNextDiscussion
+ "
class="btn-group discussion-actions ml-sm-2"
>
<jump-to-next-discussion-button :from-discussion-id="discussion.id" />
diff --git a/app/assets/javascripts/notes/components/discussion_filter_note.vue b/app/assets/javascripts/notes/components/discussion_filter_note.vue
index 25ff49fbd0f..8dc4b43d69a 100644
--- a/app/assets/javascripts/notes/components/discussion_filter_note.vue
+++ b/app/assets/javascripts/notes/components/discussion_filter_note.vue
@@ -1,5 +1,5 @@
<script>
-import { GlDeprecatedButton } from '@gitlab/ui';
+import { GlButton } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
import { __, sprintf } from '~/locale';
@@ -7,7 +7,7 @@ import notesEventHub from '../event_hub';
export default {
components: {
- GlDeprecatedButton,
+ GlButton,
Icon,
},
computed: {
@@ -40,12 +40,12 @@ export default {
<div class="timeline-content">
<div ref="timelineContent" v-html="timelineContent"></div>
<div class="discussion-filter-actions mt-2">
- <gl-deprecated-button ref="showAllActivity" variant="default" @click="selectFilter(0)">
+ <gl-button ref="showAllActivity" variant="default" @click="selectFilter(0)">
{{ __('Show all activity') }}
- </gl-deprecated-button>
- <gl-deprecated-button ref="showComments" variant="default" @click="selectFilter(1)">
+ </gl-button>
+ <gl-button ref="showComments" variant="default" @click="selectFilter(1)">
{{ __('Show comments only') }}
- </gl-deprecated-button>
+ </gl-button>
</div>
</div>
</li>
diff --git a/app/assets/javascripts/notes/components/discussion_keyboard_navigator.vue b/app/assets/javascripts/notes/components/discussion_navigator.vue
index 2dc222d08f9..facc53e27a6 100644
--- a/app/assets/javascripts/notes/components/discussion_keyboard_navigator.vue
+++ b/app/assets/javascripts/notes/components/discussion_navigator.vue
@@ -2,9 +2,13 @@
/* global Mousetrap */
import 'mousetrap';
import discussionNavigation from '~/notes/mixins/discussion_navigation';
+import eventHub from '~/notes/event_hub';
export default {
mixins: [discussionNavigation],
+ created() {
+ eventHub.$on('jumpToFirstUnresolvedDiscussion', this.jumpToFirstUnresolvedDiscussion);
+ },
mounted() {
Mousetrap.bind('n', this.jumpToNextDiscussion);
Mousetrap.bind('p', this.jumpToPreviousDiscussion);
@@ -12,6 +16,8 @@ export default {
beforeDestroy() {
Mousetrap.unbind('n');
Mousetrap.unbind('p');
+
+ eventHub.$off('jumpToFirstUnresolvedDiscussion', this.jumpToFirstUnresolvedDiscussion);
},
render() {
return this.$slots.default;
diff --git a/app/assets/javascripts/notes/components/discussion_notes.vue b/app/assets/javascripts/notes/components/discussion_notes.vue
index 458da5cf67f..a1e887c47d0 100644
--- a/app/assets/javascripts/notes/components/discussion_notes.vue
+++ b/app/assets/javascripts/notes/components/discussion_notes.vue
@@ -9,6 +9,7 @@ import NoteableNote from './noteable_note.vue';
import ToggleRepliesWidget from './toggle_replies_widget.vue';
import NoteEditedText from './note_edited_text.vue';
import DiscussionNotesRepliesWrapper from './discussion_notes_replies_wrapper.vue';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
export default {
name: 'DiscussionNotes',
@@ -17,6 +18,7 @@ export default {
NoteEditedText,
DiscussionNotesRepliesWrapper,
},
+ mixins: [glFeatureFlagsMixin()],
props: {
discussion: {
type: Object,
@@ -93,6 +95,18 @@ export default {
componentData(note) {
return note.isPlaceholderNote ? note.notes[0] : note;
},
+ handleMouseEnter(discussion) {
+ if (this.glFeatures.multilineComments && discussion.position) {
+ this.setSelectedCommentPositionHover(discussion.position.line_range);
+ }
+ },
+ handleMouseLeave(discussion) {
+ // Even though position isn't used here we still don't want to unecessarily call a mutation
+ // The lack of position tells us that highlighting is irrelevant in this context
+ if (this.glFeatures.multilineComments && discussion.position) {
+ this.setSelectedCommentPositionHover();
+ }
+ },
},
};
</script>
@@ -101,8 +115,8 @@ export default {
<div class="discussion-notes">
<ul
class="notes"
- @mouseenter="setSelectedCommentPositionHover(discussion.position.line_range)"
- @mouseleave="setSelectedCommentPositionHover()"
+ @mouseenter="handleMouseEnter(discussion)"
+ @mouseleave="handleMouseLeave(discussion)"
>
<template v-if="shouldGroupReplies">
<component
diff --git a/app/assets/javascripts/notes/components/discussion_resolve_with_issue_button.vue b/app/assets/javascripts/notes/components/discussion_resolve_with_issue_button.vue
index e5f78b1c7de..cace382ccd6 100644
--- a/app/assets/javascripts/notes/components/discussion_resolve_with_issue_button.vue
+++ b/app/assets/javascripts/notes/components/discussion_resolve_with_issue_button.vue
@@ -1,12 +1,10 @@
<script>
-import { GlTooltipDirective, GlDeprecatedButton } from '@gitlab/ui';
-import Icon from '~/vue_shared/components/icon.vue';
+import { GlTooltipDirective, GlButton } from '@gitlab/ui';
export default {
name: 'ResolveWithIssueButton',
components: {
- Icon,
- GlDeprecatedButton,
+ GlButton,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -22,13 +20,12 @@ export default {
<template>
<div class="btn-group" role="group">
- <gl-deprecated-button
+ <gl-button
v-gl-tooltip
:href="url"
:title="s__('MergeRequests|Resolve this thread in a new issue')"
class="new-issue-for-discussion discussion-create-issue-btn"
- >
- <icon name="issue-new" />
- </gl-deprecated-button>
+ icon="issue-new"
+ />
</div>
</template>
diff --git a/app/assets/javascripts/notes/components/note_actions.vue b/app/assets/javascripts/notes/components/note_actions.vue
index 7615b0518b7..a8ae7fb48f0 100644
--- a/app/assets/javascripts/notes/components/note_actions.vue
+++ b/app/assets/javascripts/notes/components/note_actions.vue
@@ -1,13 +1,13 @@
<script>
-import { __ } from '~/locale';
import { mapGetters } from 'vuex';
import { GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui';
+import { __ } from '~/locale';
import resolvedStatusMixin from '~/batch_comments/mixins/resolved_status';
import Icon from '~/vue_shared/components/icon.vue';
import ReplyButton from './note_actions/reply_button.vue';
import eventHub from '~/sidebar/event_hub';
import Api from '~/api';
-import flash from '~/flash';
+import { deprecatedCreateFlash as flash } from '~/flash';
export default {
name: 'NoteActions',
diff --git a/app/assets/javascripts/notes/components/note_awards_list.vue b/app/assets/javascripts/notes/components/note_awards_list.vue
index 5181b5f26ee..cf3e991986c 100644
--- a/app/assets/javascripts/notes/components/note_awards_list.vue
+++ b/app/assets/javascripts/notes/components/note_awards_list.vue
@@ -1,7 +1,7 @@
<script>
import { mapActions, mapGetters } from 'vuex';
import AwardsList from '~/vue_shared/components/awards_list.vue';
-import Flash from '../../flash';
+import { deprecatedCreateFlash as Flash } from '../../flash';
import { __ } from '~/locale';
export default {
diff --git a/app/assets/javascripts/notes/components/note_header.vue b/app/assets/javascripts/notes/components/note_header.vue
index 81812ee2279..9ded5ab648e 100644
--- a/app/assets/javascripts/notes/components/note_header.vue
+++ b/app/assets/javascripts/notes/components/note_header.vue
@@ -191,7 +191,7 @@ export default {
name="eye-slash"
:size="14"
:title="s__('Notes|Private comments are accessible by internal staff only')"
- class="gl-ml-1 gl-text-gray-800 align-middle"
+ class="gl-ml-1 gl-text-gray-700 align-middle"
/>
<slot name="extra-controls"></slot>
<i
diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue
index 7fe50d36c0c..b4176c6063b 100644
--- a/app/assets/javascripts/notes/components/noteable_discussion.vue
+++ b/app/assets/javascripts/notes/components/noteable_discussion.vue
@@ -7,7 +7,7 @@ import { clearDraft, getDiscussionReplyKey } from '~/lib/utils/autosave';
import icon from '~/vue_shared/components/icon.vue';
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
import DraftNote from '~/batch_comments/components/draft_note.vue';
-import Flash from '../../flash';
+import { deprecatedCreateFlash as Flash } from '../../flash';
import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
import diffDiscussionHeader from './diff_discussion_header.vue';
import noteSignedOutWidget from './note_signed_out_widget.vue';
@@ -149,9 +149,14 @@ export default {
'removePlaceholderNotes',
'toggleResolveNote',
'removeConvertedDiscussion',
+ 'expandDiscussion',
]),
showReplyForm() {
this.isReplying = true;
+
+ if (!this.discussion.expanded) {
+ this.expandDiscussion({ discussionId: this.discussion.id });
+ }
},
cancelReplyForm(shouldConfirm, isDirty) {
if (shouldConfirm && isDirty) {
diff --git a/app/assets/javascripts/notes/components/noteable_note.vue b/app/assets/javascripts/notes/components/noteable_note.vue
index 9bf8cffe940..ce771e67cbb 100644
--- a/app/assets/javascripts/notes/components/noteable_note.vue
+++ b/app/assets/javascripts/notes/components/noteable_note.vue
@@ -7,7 +7,7 @@ import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { truncateSha } from '~/lib/utils/text_utility';
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
import { __, s__, sprintf } from '../../locale';
-import Flash from '../../flash';
+import { deprecatedCreateFlash as Flash } from '../../flash';
import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
import noteHeader from './note_header.vue';
import noteActions from './note_actions.vue';
@@ -23,7 +23,6 @@ import {
commentLineOptions,
formatLineRange,
} from './multiline_comment_utils';
-import MultilineCommentForm from './multiline_comment_form.vue';
export default {
name: 'NoteableNote',
@@ -34,7 +33,6 @@ export default {
noteActions,
NoteBody,
TimelineEntryItem,
- MultilineCommentForm,
},
mixins: [noteable, resolvable, glFeatureFlagsMixin()],
props: {
@@ -147,14 +145,17 @@ export default {
return getEndLineNumber(this.lineRange);
},
showMultiLineComment() {
- if (!this.glFeatures.multilineComments || !this.discussionRoot) return false;
- if (this.isEditing) return true;
+ if (
+ !this.glFeatures.multilineComments ||
+ !this.discussionRoot ||
+ this.startLineNumber.length === 0 ||
+ this.endLineNumber.length === 0
+ )
+ return false;
return this.line && this.startLineNumber !== this.endLineNumber;
},
commentLineOptions() {
- if (!this.diffFile || !this.line) return [];
-
const sideA = this.line.type === 'new' ? 'right' : 'left';
const sideB = sideA === 'left' ? 'right' : 'left';
const lines = this.diffFile.highlighted_diff_lines.length
@@ -207,6 +208,7 @@ export default {
'scrollToNoteIfNeeded',
'updateAssignees',
'setSelectedCommentPositionHover',
+ 'updateDiscussionPosition',
]),
editHandler() {
this.isEditing = true;
@@ -249,8 +251,13 @@ export default {
...this.note.position,
};
- if (this.commentLineStart && this.line)
+ if (this.discussionRoot && this.commentLineStart && this.line) {
position.line_range = formatLineRange(this.commentLineStart, this.line);
+ this.updateDiscussionPosition({
+ discussionId: this.note.discussion_id,
+ position,
+ });
+ }
this.$emit('handleUpdateNote', {
note: this.note,
@@ -337,28 +344,19 @@ export default {
:data-note-id="note.id"
class="note note-wrapper qa-noteable-note-item"
>
- <div v-if="showMultiLineComment" data-testid="multiline-comment">
- <multiline-comment-form
- v-if="isEditing && note.position"
- v-model="commentLineStart"
- :line="line"
- :comment-line-options="commentLineOptions"
- :line-range="note.position.line_range"
- class="gl-mb-3 gl-text-gray-700 gl-pb-3"
- />
- <div
- v-else
- class="gl-mb-3 gl-text-gray-700 gl-border-gray-200 gl-border-b-solid gl-border-b-1 gl-pb-3"
- >
- <gl-sprintf :message="__('Comment on lines %{startLine} to %{endLine}')">
- <template #startLine>
- <span :class="getLineClasses(startLineNumber)">{{ startLineNumber }}</span>
- </template>
- <template #endLine>
- <span :class="getLineClasses(endLineNumber)">{{ endLineNumber }}</span>
- </template>
- </gl-sprintf>
- </div>
+ <div
+ v-if="showMultiLineComment"
+ data-testid="multiline-comment"
+ class="gl-mb-3 gl-text-gray-500 gl-border-gray-200 gl-border-b-solid gl-border-b-1 gl-pb-3"
+ >
+ <gl-sprintf :message="__('Comment on lines %{startLine} to %{endLine}')">
+ <template #startLine>
+ <span :class="getLineClasses(startLineNumber)">{{ startLineNumber }}</span>
+ </template>
+ <template #endLine>
+ <span :class="getLineClasses(endLineNumber)">{{ endLineNumber }}</span>
+ </template>
+ </gl-sprintf>
</div>
<div v-once class="timeline-icon">
<user-avatar-link
diff --git a/app/assets/javascripts/notes/components/notes_app.vue b/app/assets/javascripts/notes/components/notes_app.vue
index faa6006945d..fb18be9386e 100644
--- a/app/assets/javascripts/notes/components/notes_app.vue
+++ b/app/assets/javascripts/notes/components/notes_app.vue
@@ -1,7 +1,7 @@
<script>
import { mapGetters, mapActions } from 'vuex';
import { getLocationHash, doesHashExistInUrl } from '../../lib/utils/url_utility';
-import Flash from '../../flash';
+import { deprecatedCreateFlash as Flash } from '../../flash';
import * as constants from '../constants';
import eventHub from '../event_hub';
import noteableNote from './noteable_note.vue';
@@ -136,6 +136,8 @@ export default {
}
window.addEventListener('hashchange', this.handleHashChanged);
+
+ eventHub.$on('notesApp.updateIssuableConfidentiality', this.setConfidentiality);
},
updated() {
this.$nextTick(() => {
@@ -146,6 +148,7 @@ export default {
beforeDestroy() {
this.stopPolling();
window.removeEventListener('hashchange', this.handleHashChanged);
+ eventHub.$off('notesApp.updateIssuableConfidentiality', this.setConfidentiality);
},
methods: {
...mapActions([
@@ -164,6 +167,7 @@ export default {
'startTaskList',
'convertToDiscussion',
'stopPolling',
+ 'setConfidentiality',
]),
discussionIsIndividualNoteAndNotConverted(discussion) {
return discussion.individual_note && !this.convertedDisscussionIds.includes(discussion.id);
diff --git a/app/assets/javascripts/notes/event_hub.js b/app/assets/javascripts/notes/event_hub.js
index 0948c2e5352..e31806ad199 100644
--- a/app/assets/javascripts/notes/event_hub.js
+++ b/app/assets/javascripts/notes/event_hub.js
@@ -1,3 +1,3 @@
-import Vue from 'vue';
+import createEventHub from '~/helpers/event_hub_factory';
-export default new Vue();
+export default createEventHub();
diff --git a/app/assets/javascripts/notes/index.js b/app/assets/javascripts/notes/index.js
index ba814649078..7bf465482b3 100644
--- a/app/assets/javascripts/notes/index.js
+++ b/app/assets/javascripts/notes/index.js
@@ -20,6 +20,11 @@ document.addEventListener('DOMContentLoaded', () => {
noteableData.noteableType = notesDataset.noteableType;
noteableData.targetType = notesDataset.targetType;
+ if (noteableData.discussion_locked === null) {
+ // discussion_locked has never been set for this issuable.
+ // set to `false` for safety.
+ noteableData.discussion_locked = false;
+ }
if (parsedUserData) {
currentUserData = {
diff --git a/app/assets/javascripts/notes/mixins/diff_line_note_form.js b/app/assets/javascripts/notes/mixins/diff_line_note_form.js
index 9a2e86aeed2..c4a42eb1a98 100644
--- a/app/assets/javascripts/notes/mixins/diff_line_note_form.js
+++ b/app/assets/javascripts/notes/mixins/diff_line_note_form.js
@@ -1,7 +1,7 @@
import { mapActions, mapGetters, mapState } from 'vuex';
import { getDraftReplyFormData, getDraftFormData } from '~/batch_comments/utils';
import { TEXT_DIFF_POSITION_TYPE, IMAGE_DIFF_POSITION_TYPE } from '~/diffs/constants';
-import createFlash from '~/flash';
+import { deprecatedCreateFlash as createFlash } from '~/flash';
import { s__ } from '~/locale';
import { clearDraft } from '~/lib/utils/autosave';
import { formatLineRange } from '~/notes/components/multiline_comment_utils';
diff --git a/app/assets/javascripts/notes/mixins/discussion_navigation.js b/app/assets/javascripts/notes/mixins/discussion_navigation.js
index 889883a23d0..61298a15c5d 100644
--- a/app/assets/javascripts/notes/mixins/discussion_navigation.js
+++ b/app/assets/javascripts/notes/mixins/discussion_navigation.js
@@ -78,7 +78,7 @@ function handleDiscussionJump(self, fn, discussionId = self.currentDiscussionId)
const isDiffView = window.mrTabs.currentAction === 'diffs';
const targetId = fn(discussionId, isDiffView);
const discussion = self.getDiscussion(targetId);
- const discussionFilePath = discussion.diff_file?.file_path;
+ const discussionFilePath = discussion?.diff_file?.file_path;
if (discussionFilePath) {
self.scrollToFile(discussionFilePath);
@@ -113,6 +113,14 @@ export default {
handleDiscussionJump(this, this.previousUnresolvedDiscussionId);
},
+ jumpToFirstUnresolvedDiscussion() {
+ this.setCurrentDiscussionId(null)
+ .then(() => {
+ this.jumpToNextDiscussion();
+ })
+ .catch(() => {});
+ },
+
/**
* Go to the next discussion from the given discussionId
* @param {String} discussionId The id we are jumping from
diff --git a/app/assets/javascripts/notes/mixins/resolvable.js b/app/assets/javascripts/notes/mixins/resolvable.js
index 16b7598ee09..087b5828cce 100644
--- a/app/assets/javascripts/notes/mixins/resolvable.js
+++ b/app/assets/javascripts/notes/mixins/resolvable.js
@@ -1,4 +1,4 @@
-import Flash from '~/flash';
+import { deprecatedCreateFlash as Flash } from '~/flash';
import { __ } from '~/locale';
export default {
diff --git a/app/assets/javascripts/notes/stores/actions.js b/app/assets/javascripts/notes/stores/actions.js
index 5b2ab255557..f6069b509e8 100644
--- a/app/assets/javascripts/notes/stores/actions.js
+++ b/app/assets/javascripts/notes/stores/actions.js
@@ -3,7 +3,7 @@ import $ from 'jquery';
import Visibility from 'visibilityjs';
import axios from '~/lib/utils/axios_utils';
import TaskList from '../../task_list';
-import Flash from '../../flash';
+import { deprecatedCreateFlash as Flash } from '../../flash';
import Poll from '../../lib/utils/poll';
import * as types from './mutation_types';
import * as utils from './utils';
@@ -13,32 +13,35 @@ import sidebarTimeTrackingEventHub from '../../sidebar/event_hub';
import { isInViewport, scrollToElement, isInMRPage } from '../../lib/utils/common_utils';
import { mergeUrlParams } from '../../lib/utils/url_utility';
import mrWidgetEventHub from '../../vue_merge_request_widget/event_hub';
-import updateIssueConfidentialMutation from '~/sidebar/components/confidential/queries/update_issue_confidential.mutation.graphql';
+import updateIssueConfidentialMutation from '~/sidebar/components/confidential/mutations/update_issue_confidential.mutation.graphql';
+import updateMergeRequestLockMutation from '~/sidebar/components/lock/mutations/update_merge_request_lock.mutation.graphql';
+import updateIssueLockMutation from '~/sidebar/components/lock/mutations/update_issue_lock.mutation.graphql';
import { __, sprintf } from '~/locale';
import Api from '~/api';
let eTagPoll;
-export const updateConfidentialityOnIssue = ({ commit, getters }, { confidential, fullPath }) => {
- const { iid } = getters.getNoteableData;
+export const updateLockedAttribute = ({ commit, getters }, { locked, fullPath }) => {
+ const { iid, targetType } = getters.getNoteableData;
return utils.gqClient
.mutate({
- mutation: updateIssueConfidentialMutation,
+ mutation: targetType === 'issue' ? updateIssueLockMutation : updateMergeRequestLockMutation,
variables: {
input: {
projectPath: fullPath,
iid: String(iid),
- confidential,
+ locked,
},
},
})
.then(({ data }) => {
- const {
- issueSetConfidential: { issue },
- } = data;
+ const discussionLocked =
+ targetType === 'issue'
+ ? data.issueSetLocked.issue.discussionLocked
+ : data.mergeRequestSetLocked.mergeRequest.discussionLocked;
- commit(types.SET_ISSUE_CONFIDENTIAL, issue.confidential);
+ commit(types.SET_ISSUABLE_LOCK, discussionLocked);
});
};
@@ -683,5 +686,32 @@ export const updateAssignees = ({ commit }, assignees) => {
commit(types.UPDATE_ASSIGNEES, assignees);
};
-// prevent babel-plugin-rewire from generating an invalid default during karma tests
-export default () => {};
+export const updateDiscussionPosition = ({ commit }, updatedPosition) => {
+ commit(types.UPDATE_DISCUSSION_POSITION, updatedPosition);
+};
+
+export const updateConfidentialityOnIssuable = (
+ { getters, commit },
+ { confidential, fullPath },
+) => {
+ const { iid } = getters.getNoteableData;
+
+ return utils.gqClient
+ .mutate({
+ mutation: updateIssueConfidentialMutation,
+ variables: {
+ input: {
+ projectPath: fullPath,
+ iid: String(iid),
+ confidential,
+ },
+ },
+ })
+ .then(({ data }) => {
+ const {
+ issueSetConfidential: { issue },
+ } = data;
+
+ setConfidentiality({ commit }, issue.confidential);
+ });
+};
diff --git a/app/assets/javascripts/notes/stores/getters.js b/app/assets/javascripts/notes/stores/getters.js
index 85997b44bcc..7d60fbffb10 100644
--- a/app/assets/javascripts/notes/stores/getters.js
+++ b/app/assets/javascripts/notes/stores/getters.js
@@ -194,7 +194,9 @@ export const findUnresolvedDiscussionIdNeighbor = (state, getters) => ({
diffOrder,
step,
}) => {
- const ids = getters.unresolvedDiscussionsIdsOrdered(diffOrder);
+ const diffIds = getters.unresolvedDiscussionsIdsOrdered(diffOrder);
+ const dateIds = getters.unresolvedDiscussionsIdsOrdered(false);
+ const ids = diffIds.length ? diffIds : dateIds;
const index = ids.indexOf(discussionId) + step;
if (index < 0 && step < 0) {
@@ -229,6 +231,3 @@ export const getDiscussion = state => discussionId =>
state.discussions.find(discussion => discussion.id === discussionId);
export const commentsDisabled = state => state.commentsDisabled;
-
-// prevent babel-plugin-rewire from generating an invalid default during karma tests
-export default () => {};
diff --git a/app/assets/javascripts/notes/stores/mutation_types.js b/app/assets/javascripts/notes/stores/mutation_types.js
index f2236b18beb..eb3447291bc 100644
--- a/app/assets/javascripts/notes/stores/mutation_types.js
+++ b/app/assets/javascripts/notes/stores/mutation_types.js
@@ -12,6 +12,7 @@ export const SHOW_PLACEHOLDER_NOTE = 'SHOW_PLACEHOLDER_NOTE';
export const TOGGLE_AWARD = 'TOGGLE_AWARD';
export const UPDATE_NOTE = 'UPDATE_NOTE';
export const UPDATE_DISCUSSION = 'UPDATE_DISCUSSION';
+export const UPDATE_DISCUSSION_POSITION = 'UPDATE_DISCUSSION_POSITION';
export const SET_DISCUSSION_DIFF_LINES = 'SET_DISCUSSION_DIFF_LINES';
export const SET_NOTES_FETCHED_STATE = 'SET_NOTES_FETCHED_STATE';
export const SET_NOTES_LOADING_STATE = 'SET_NOTES_LOADING_STATE';
@@ -42,6 +43,7 @@ export const REOPEN_ISSUE = 'REOPEN_ISSUE';
export const TOGGLE_STATE_BUTTON_LOADING = 'TOGGLE_STATE_BUTTON_LOADING';
export const TOGGLE_BLOCKED_ISSUE_WARNING = 'TOGGLE_BLOCKED_ISSUE_WARNING';
export const SET_ISSUE_CONFIDENTIAL = 'SET_ISSUE_CONFIDENTIAL';
+export const SET_ISSUABLE_LOCK = 'SET_ISSUABLE_LOCK';
// Description version
export const REQUEST_DESCRIPTION_VERSION = 'REQUEST_DESCRIPTION_VERSION';
diff --git a/app/assets/javascripts/notes/stores/mutations.js b/app/assets/javascripts/notes/stores/mutations.js
index e5f1c11fb35..aa078f00569 100644
--- a/app/assets/javascripts/notes/stores/mutations.js
+++ b/app/assets/javascripts/notes/stores/mutations.js
@@ -99,6 +99,10 @@ export default {
state.noteableData.confidential = data;
},
+ [types.SET_ISSUABLE_LOCK](state, locked) {
+ state.noteableData.discussion_locked = locked;
+ },
+
[types.SET_USER_DATA](state, data) {
Object.assign(state, { userData: data });
},
@@ -274,6 +278,11 @@ export default {
Object.assign(selectedDiscussion, { ...note });
},
+ [types.UPDATE_DISCUSSION_POSITION](state, { discussionId, position }) {
+ const selectedDiscussion = state.discussions.find(disc => disc.id === discussionId);
+ if (selectedDiscussion) Object.assign(selectedDiscussion.position, { ...position });
+ },
+
[types.CLOSE_ISSUE](state) {
Object.assign(state.noteableData, { state: constants.CLOSED });
},