diff --git a/app/assets/javascripts/diffs/components/diff_line_note_form.vue b/app/assets/javascripts/diffs/components/diff_line_note_form.vue
index 9fd02acbd6e..e7569ba7b84 100644
--- a/app/assets/javascripts/diffs/components/diff_line_note_form.vue
+++ b/app/assets/javascripts/diffs/components/diff_line_note_form.vue
@@ -94,6 +94,7 @@ export default {
ref="noteForm"
:is-editing="true"
:line-code="line.line_code"
+ :line="line"
save-button-title="Comment"
class="diff-comment-form"
@cancelForm="handleCancelCommentForm"
diff --git a/app/assets/javascripts/diffs/components/inline_diff_comment_row.vue b/app/assets/javascripts/diffs/components/inline_diff_comment_row.vue
index aa40b24950a..814ee0b7c02 100644
--- a/app/assets/javascripts/diffs/components/inline_diff_comment_row.vue
+++ b/app/assets/javascripts/diffs/components/inline_diff_comment_row.vue
@@ -16,6 +16,11 @@ export default {
type: String,
required: true,
},
+ helpPagePath: {
+ type: String,
+ required: false,
+ default: '',
+ },
},
computed: {
className() {
@@ -38,7 +43,12 @@ export default {
-
+
diff --git a/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue b/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue
index b98463d3dd3..a65cf025cde 100644
--- a/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue
+++ b/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue
@@ -20,6 +20,11 @@ export default {
type: Number,
required: true,
},
+ helpPagePath: {
+ type: String,
+ required: false,
+ default: '',
+ },
},
computed: {
hasExpandedDiscussionOnLeft() {
@@ -87,6 +92,8 @@ export default {
diff --git a/app/assets/javascripts/diffs/index.js b/app/assets/javascripts/diffs/index.js
index 915cacb374f..b130cedc24c 100644
--- a/app/assets/javascripts/diffs/index.js
+++ b/app/assets/javascripts/diffs/index.js
@@ -16,6 +16,7 @@ export default function initDiffsApp(store) {
return {
endpoint: dataset.endpoint,
projectPath: dataset.projectPath,
+ helpPagePath: dataset.helpPagePath,
currentUser: JSON.parse(dataset.currentUserData) || {},
changesEmptyStateIllustration: dataset.changesEmptyStateIllustration,
};
@@ -31,6 +32,7 @@ export default function initDiffsApp(store) {
endpoint: this.endpoint,
currentUser: this.currentUser,
projectPath: this.projectPath,
+ helpPagePath: this.helpPagePath,
shouldShow: this.activeTab === 'diffs',
changesEmptyStateIllustration: this.changesEmptyStateIllustration,
},
diff --git a/app/assets/javascripts/lib/utils/text_markdown.js b/app/assets/javascripts/lib/utils/text_markdown.js
index 3618c6af7e2..c095a017866 100644
--- a/app/assets/javascripts/lib/utils/text_markdown.js
+++ b/app/assets/javascripts/lib/utils/text_markdown.js
@@ -39,7 +39,14 @@ function blockTagText(text, textArea, blockTag, selected) {
}
}
-function moveCursor({ textArea, tag, positionBetweenTags, removedLastNewLine, select }) {
+function moveCursor({
+ textArea,
+ tag,
+ cursorOffset,
+ positionBetweenTags,
+ removedLastNewLine,
+ select,
+}) {
var pos;
if (!textArea.setSelectionRange) {
return;
@@ -61,11 +68,24 @@ function moveCursor({ textArea, tag, positionBetweenTags, removedLastNewLine, se
pos -= 1;
}
+ if (cursorOffset) {
+ pos -= cursorOffset;
+ }
+
return textArea.setSelectionRange(pos, pos);
}
}
-export function insertMarkdownText({ textArea, text, tag, blockTag, selected, wrap, select }) {
+export function insertMarkdownText({
+ textArea,
+ text,
+ tag,
+ cursorOffset,
+ blockTag,
+ selected,
+ wrap,
+ select,
+}) {
var textToInsert,
selectedSplit,
startChar,
@@ -154,20 +174,30 @@ export function insertMarkdownText({ textArea, text, tag, blockTag, selected, wr
return moveCursor({
textArea,
tag: tag.replace(textPlaceholder, selected),
+ cursorOffset,
positionBetweenTags: wrap && selected.length === 0,
removedLastNewLine,
select,
});
}
-function updateText({ textArea, tag, blockTag, wrap, select }) {
+function updateText({ textArea, tag, cursorOffset, blockTag, wrap, select, tagContent }) {
var $textArea, selected, text;
$textArea = $(textArea);
textArea = $textArea.get(0);
text = $textArea.val();
- selected = selectedText(text, textArea);
+ selected = selectedText(text, textArea) || tagContent;
$textArea.focus();
- return insertMarkdownText({ textArea, text, tag, blockTag, selected, wrap, select });
+ return insertMarkdownText({
+ textArea,
+ text,
+ tag,
+ cursorOffset,
+ blockTag,
+ selected,
+ wrap,
+ select,
+ });
}
export function addMarkdownListeners(form) {
@@ -178,9 +208,11 @@ export function addMarkdownListeners(form) {
return updateText({
textArea: $this.closest('.md-area').find('textarea'),
tag: $this.data('mdTag'),
+ cursorOffset: $this.data('mdCursorOffset'),
blockTag: $this.data('mdBlock'),
wrap: !$this.data('mdPrepend'),
select: $this.data('mdSelect'),
+ tagContent: $this.data('mdTagContent').toString(),
});
});
}
diff --git a/app/assets/javascripts/mr_notes/index.js b/app/assets/javascripts/mr_notes/index.js
index 1c98683c597..e4d72eb8318 100644
--- a/app/assets/javascripts/mr_notes/index.js
+++ b/app/assets/javascripts/mr_notes/index.js
@@ -33,6 +33,7 @@ export default function initMrNotes() {
noteableData,
currentUserData: JSON.parse(notesDataset.currentUserData),
notesData: JSON.parse(notesDataset.notesData),
+ helpPagePath: notesDataset.helpPagePath,
};
},
computed: {
@@ -71,6 +72,7 @@ export default function initMrNotes() {
notesData: this.notesData,
userData: this.currentUserData,
shouldShow: this.activeTab === 'show',
+ helpPagePath: this.helpPagePath,
},
});
},
diff --git a/app/assets/javascripts/notes/components/note_body.vue b/app/assets/javascripts/notes/components/note_body.vue
index c0bee600181..bcf5d334da4 100644
--- a/app/assets/javascripts/notes/components/note_body.vue
+++ b/app/assets/javascripts/notes/components/note_body.vue
@@ -1,10 +1,12 @@
-
+
+
+import { mergeUrlParams } from '~/lib/utils/url_utility';
import { mapGetters, mapActions } from 'vuex';
import eventHub from '../event_hub';
import issueWarning from '../../vue_shared/components/issue/issue_warning.vue';
@@ -53,6 +54,21 @@ export default {
required: false,
default: false,
},
+ line: {
+ type: Object,
+ required: false,
+ default: null,
+ },
+ note: {
+ type: Object,
+ required: false,
+ default: null,
+ },
+ helpPagePath: {
+ type: String,
+ required: false,
+ default: '',
+ },
},
data() {
return {
@@ -79,7 +95,8 @@ export default {
return '#';
},
markdownPreviewPath() {
- return this.getNoteableDataByProp('preview_note_path');
+ const notable = this.getNoteableDataByProp('preview_note_path');
+ return mergeUrlParams({ preview_suggestions: true }, notable);
},
markdownDocsPath() {
return this.getNotesDataByProp('markdownDocsPath');
@@ -93,6 +110,18 @@ export default {
isDisabled() {
return !this.updatedNoteBody.length || this.isSubmitting;
},
+ discussionNote() {
+ const discussionNote = this.discussion.id
+ ? this.getDiscussionLastNote(this.discussion)
+ : this.note;
+ return discussionNote || {};
+ },
+ canSuggest() {
+ return (
+ this.getNoteableData.can_receive_suggestion &&
+ (this.line && this.line.can_receive_suggestion)
+ );
+ },
},
watch: {
noteBody() {
@@ -171,7 +200,11 @@ export default {
:markdown-docs-path="markdownDocsPath"
:markdown-version="markdownVersion"
:quick-actions-docs-path="quickActionsDocsPath"
+ :line="line"
+ :note="discussionNote"
+ :can-suggest="canSuggest"
:add-spacing-classes="false"
+ :help-page-path="helpPagePath"
>
|