summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Knox <psimyn@gmail.com>2018-03-23 19:13:02 +1100
committerSimon Knox <psimyn@gmail.com>2018-03-23 19:13:02 +1100
commit62433270ffc9ba25381e2e66e285f4fc76bf5f97 (patch)
tree7e65e5f02d6c69227e83f011e4acb65eeb0059ea
parent7fdd7abab095897c20e4a1759614d27587fb76cd (diff)
parente17549213806a87986d04812d16ba20cea2298de (diff)
downloadgitlab-ce-62433270ffc9ba25381e2e66e285f4fc76bf5f97.tar.gz
Merge branch 'changes_tab_vue_refactoring' of gitlab.com:gitlab-org/gitlab-ce into changes_tab_vue_refactoring
-rw-r--r--app/assets/javascripts/diffs/components/diff_line_gutter_content.vue85
-rw-r--r--app/assets/javascripts/diffs/components/inline_diff_view.vue24
-rw-r--r--app/assets/javascripts/diffs/components/parallel_diff_view.vue18
-rw-r--r--app/assets/javascripts/diffs/constants.js4
-rw-r--r--app/assets/javascripts/diffs/mixins/diff_content.js19
-rw-r--r--app/assets/javascripts/diffs/store/actions.js24
-rw-r--r--app/assets/javascripts/diffs/store/mutation_types.js1
-rw-r--r--app/assets/javascripts/diffs/store/mutations.js17
-rw-r--r--app/assets/javascripts/diffs/store/utils.js103
-rw-r--r--app/assets/javascripts/merge_request_tabs.js3
-rw-r--r--app/assets/javascripts/mr_notes/index.js13
-rw-r--r--app/assets/javascripts/mr_notes/stores/getters.js4
-rw-r--r--app/assets/javascripts/notes/components/diff_file_header.vue1
-rw-r--r--app/assets/javascripts/notes/stores/actions.js1
-rw-r--r--app/assets/javascripts/notes/stores/getters.js4
-rw-r--r--app/assets/stylesheets/pages/diff.scss6
-rw-r--r--app/serializers/diff_file_entity.rb2
17 files changed, 301 insertions, 28 deletions
diff --git a/app/assets/javascripts/diffs/components/diff_line_gutter_content.vue b/app/assets/javascripts/diffs/components/diff_line_gutter_content.vue
index d8c57b8a629..4a9aff12ba9 100644
--- a/app/assets/javascripts/diffs/components/diff_line_gutter_content.vue
+++ b/app/assets/javascripts/diffs/components/diff_line_gutter_content.vue
@@ -1,8 +1,14 @@
<script>
-import { MATCH_LINE_TYPE } from '../constants';
+import { mapState, mapGetters, mapActions } from 'vuex';
+import { MATCH_LINE_TYPE, UNFOLD_COUNT, CONTEXT_LINE_TYPE } from '../constants';
+import * as utils from '../store/utils';
export default {
props: {
+ fileHash: {
+ type: String,
+ required: true,
+ },
lineType: {
type: String,
required: false,
@@ -23,39 +29,110 @@ export default {
required: false,
default: '',
},
+ metaData: {
+ type: Object,
+ required: false,
+ default: () => ({}),
+ },
showCommentButton: {
type: Boolean,
required: false,
default: false,
},
+ contextLinesPath: {
+ type: String,
+ required: true,
+ },
+ isBottom: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
computed: {
+ ...mapState({
+ diffViewType: state => state.diffs.diffViewType,
+ diffFiles: state => state.diffs.diffFiles,
+ }),
+ ...mapGetters(['isLoggedIn']),
isMatchLine() {
return this.lineType === MATCH_LINE_TYPE;
},
+ isContextLine() {
+ return this.lineType === CONTEXT_LINE_TYPE;
+ },
getLineHref() {
- return `#${this.lineCode}`;
+ return this.lineCode ? `#${this.lineCode}` : '#';
+ },
+ shouldShowCommentButton() {
+ return (
+ this.isLoggedIn &&
+ this.showCommentButton &&
+ !this.isMatchLine &&
+ !this.isContextLine
+ );
},
},
methods: {
+ ...mapActions(['loadMoreLines']),
handleCommentButton() {
this.$emit('showCommentForm', {
lineCode: this.lineCode,
linePosition: this.linePosition,
});
},
+ handleLoadMoreLines() {
+ const endpoint = this.contextLinesPath;
+ const oldLineNumber = this.metaData.oldPos || 0;
+ const newLineNumber = this.metaData.newPos || 0;
+ const offset = newLineNumber - oldLineNumber;
+ const bottom = this.isBottom;
+ const fileHash = this.fileHash;
+ const view = this.diffViewType;
+ let unfold = true;
+ let lineNumber = newLineNumber - 1;
+ let since = lineNumber - UNFOLD_COUNT;
+ let to = lineNumber;
+
+ if (bottom) {
+ lineNumber = newLineNumber + 1;
+ since = lineNumber;
+ to = lineNumber + UNFOLD_COUNT;
+ } else {
+ const diffFile = utils.findDiffFile(this.diffFiles, this.fileHash);
+ const indexForInline = utils.findIndexInInlineLines(
+ diffFile.highlightedDiffLines,
+ { oldLineNumber, newLineNumber },
+ );
+ const prevLine = diffFile.highlightedDiffLines[indexForInline - 2];
+ const prevLineNumber = (prevLine && prevLine.newLine) || 0;
+
+ if (since <= prevLineNumber + 1) {
+ since = prevLineNumber + 1;
+ unfold = false;
+ }
+ }
+
+ const params = { since, to, bottom, offset, unfold, view };
+ const lineNumbers = { oldLineNumber, newLineNumber };
+ this.loadMoreLines({ endpoint, params, lineNumbers, fileHash });
+ },
},
};
</script>
<template>
<div>
- <span v-if="isMatchLine">...</span>
+ <span
+ v-if="isMatchLine"
+ @click="handleLoadMoreLines"
+ class="context-cell"
+ >...</span>
<template
v-else
>
<button
- v-if="showCommentButton"
+ v-if="shouldShowCommentButton"
@click="handleCommentButton"
type="button"
class="add-diff-note js-add-diff-note-button"
diff --git a/app/assets/javascripts/diffs/components/inline_diff_view.vue b/app/assets/javascripts/diffs/components/inline_diff_view.vue
index 32de9554ce5..82e4497cd15 100644
--- a/app/assets/javascripts/diffs/components/inline_diff_view.vue
+++ b/app/assets/javascripts/diffs/components/inline_diff_view.vue
@@ -1,6 +1,11 @@
<script>
import diffContentMixin from '../mixins/diff_content';
-import { MATCH_LINE_TYPE, LINE_HOVER_CLASS_NAME } from '../constants';
+import {
+ MATCH_LINE_TYPE,
+ CONTEXT_LINE_TYPE,
+ LINE_HOVER_CLASS_NAME,
+ LINE_UNFOLD_CLASS_NAME,
+} from '../constants';
export default {
mixins: [diffContentMixin],
@@ -11,10 +16,13 @@ export default {
getLineClass(line) {
const isSameLine = this.hoveredLineCode === line.lineCode;
const isMatchLine = line.type === MATCH_LINE_TYPE;
+ const isContextLine = line.type === CONTEXT_LINE_TYPE;
return {
- [line.type]: true,
- [LINE_HOVER_CLASS_NAME]: isSameLine && !isMatchLine,
+ [line.type]: line.type,
+ [LINE_HOVER_CLASS_NAME]:
+ this.isLoggedIn && isSameLine && !isMatchLine && !isContextLine,
+ [LINE_UNFOLD_CLASS_NAME]: this.isLoggedIn && isMatchLine,
};
},
},
@@ -32,7 +40,7 @@ export default {
<tr
:id="line.lineCode"
:key="line.lineCode"
- :class="line.type"
+ :class="getRowClass(line)"
class="line_holder"
@mouseover="handleMouse(line.lineCode, true)"
@mouseout="handleMouse(line.lineCode, false)"
@@ -42,10 +50,14 @@ export default {
class="diff-line-num old_line"
>
<diff-line-gutter-content
+ :file-hash="fileHash"
:line-type="line.type"
:line-code="line.lineCode"
:line-number="line.oldLine"
+ :meta-data="line.metaData"
:show-comment-button="true"
+ :context-lines-path="diffFile.contextLinesPath"
+ :is-bottom="index + 1 === diffLinesLength"
@showCommentForm="handleShowCommentForm"
/>
</td>
@@ -54,9 +66,13 @@ export default {
class="diff-line-num new_line"
>
<diff-line-gutter-content
+ :file-hash="fileHash"
:line-type="line.type"
:line-code="line.lineCode"
:line-number="line.newLine"
+ :meta-data="line.metaData"
+ :is-bottom="index + 1 === diffLinesLength"
+ :context-lines-path="diffFile.contextLinesPath"
/>
</td>
<td
diff --git a/app/assets/javascripts/diffs/components/parallel_diff_view.vue b/app/assets/javascripts/diffs/components/parallel_diff_view.vue
index 922f8e58dec..8ab3d7cdf6f 100644
--- a/app/assets/javascripts/diffs/components/parallel_diff_view.vue
+++ b/app/assets/javascripts/diffs/components/parallel_diff_view.vue
@@ -3,7 +3,9 @@ import diffContentMixin from '../mixins/diff_content';
import {
EMPTY_CELL_TYPE,
MATCH_LINE_TYPE,
+ CONTEXT_LINE_TYPE,
LINE_HOVER_CLASS_NAME,
+ LINE_UNFOLD_CLASS_NAME,
} from '../constants';
export default {
@@ -31,14 +33,17 @@ export default {
},
getClassName(line, position) {
const { type, lineCode } = line[position];
+ const isMatchLine = type === MATCH_LINE_TYPE;
const isContextLine =
- type !== MATCH_LINE_TYPE && type !== EMPTY_CELL_TYPE;
+ !isMatchLine && type !== EMPTY_CELL_TYPE && type !== CONTEXT_LINE_TYPE;
const isSameLine = this.hoveredLineCode === lineCode;
const isSameSection = position === this.hoveredSection;
return {
[type]: type,
- [LINE_HOVER_CLASS_NAME]: isContextLine && isSameLine && isSameSection,
+ [LINE_HOVER_CLASS_NAME]:
+ this.isLoggedIn && isContextLine && isSameLine && isSameSection,
+ [LINE_UNFOLD_CLASS_NAME]: this.isLoggedIn && isMatchLine,
};
},
handleMouse(e, line, isHover) {
@@ -72,6 +77,7 @@ export default {
>
<tr
:key="index"
+ :class="getRowClass(line)"
class="line_holder parallel"
@mouseover="handleMouse($event, line, true)"
@mouseout="handleMouse($event, line, false)"
@@ -82,10 +88,14 @@ export default {
class="diff-line-num old_line"
>
<diff-line-gutter-content
+ :file-hash="fileHash"
:line-type="line.left.type"
:line-code="line.left.lineCode"
:line-number="line.left.oldLine"
+ :meta-data="line.left.metaData"
:show-comment-button="true"
+ :context-lines-path="diffFile.contextLinesPath"
+ :is-bottom="index + 1 === diffLinesLength"
line-position="left"
@showCommentForm="handleShowCommentForm"
/>
@@ -103,10 +113,14 @@ export default {
class="diff-line-num new_line"
>
<diff-line-gutter-content
+ :file-hash="fileHash"
:line-type="line.right.type"
:line-code="line.right.lineCode"
:line-number="line.right.newLine"
+ :meta-data="line.right.metaData"
:show-comment-button="true"
+ :context-lines-path="diffFile.contextLinesPath"
+ :is-bottom="index + 1 === diffLinesLength"
line-position="right"
@showCommentForm="handleShowCommentForm"
/>
diff --git a/app/assets/javascripts/diffs/constants.js b/app/assets/javascripts/diffs/constants.js
index fa8cccbc46c..f93e270575f 100644
--- a/app/assets/javascripts/diffs/constants.js
+++ b/app/assets/javascripts/diffs/constants.js
@@ -1,9 +1,12 @@
export const INLINE_DIFF_VIEW_TYPE = 'inline';
export const PARALLEL_DIFF_VIEW_TYPE = 'parallel';
export const MATCH_LINE_TYPE = 'match';
+export const CONTEXT_LINE_TYPE = 'context';
export const DIFF_VIEW_COOKIE_NAME = 'diff_view';
export const EMPTY_CELL_TYPE = 'empty-cell';
export const LINE_HOVER_CLASS_NAME = 'is-over';
+export const LINE_UNFOLD_CLASS_NAME = 'unfold js-unfold';
+export const CONTEXT_LINE_CLASS_NAME = 'diff-expanded';
export const COMMENT_FORM_TYPE = 'commentForm';
export const LINE_POSITION_LEFT = 'left';
export const LINE_POSITION_RIGHT = 'right';
@@ -11,3 +14,4 @@ export const TEXT_DIFF_POSITION_TYPE = 'text';
export const DIFF_NOTE_TYPE = 'DiffNote';
export const NEW_LINE_TYPE = 'new';
export const OLD_LINE_TYPE = 'old';
+export const UNFOLD_COUNT = 20;
diff --git a/app/assets/javascripts/diffs/mixins/diff_content.js b/app/assets/javascripts/diffs/mixins/diff_content.js
index 11db6a10a3e..bb2ece68bc0 100644
--- a/app/assets/javascripts/diffs/mixins/diff_content.js
+++ b/app/assets/javascripts/diffs/mixins/diff_content.js
@@ -2,6 +2,7 @@ import { mapGetters, mapActions } from 'vuex';
import diffDiscussions from '../components/diff_discussions.vue';
import diffLineGutterContent from '../components/diff_line_gutter_content.vue';
import diffLineNoteForm from '../components/diff_line_note_form.vue';
+import { CONTEXT_LINE_TYPE, CONTEXT_LINE_CLASS_NAME } from '../constants';
export default {
props: {
@@ -26,7 +27,7 @@ export default {
diffLineGutterContent,
},
computed: {
- ...mapGetters(['discussionsByLineCode']),
+ ...mapGetters(['discussionsByLineCode', 'isLoggedIn']),
userColorScheme() {
return window.gon.user_color_scheme;
},
@@ -47,9 +48,25 @@ export default {
return line;
});
},
+ diffLinesLength() {
+ return this.normalizedDiffLines.length;
+ },
+ fileHash() {
+ return this.diffFile.fileHash;
+ },
},
methods: {
...mapActions(['showCommentForm', 'cancelCommentForm']),
+ getRowClass(line) {
+ const isContextLine = line.left
+ ? line.left.type === CONTEXT_LINE_TYPE
+ : line.type === CONTEXT_LINE_TYPE;
+
+ return {
+ [line.type]: line.type,
+ [CONTEXT_LINE_CLASS_NAME]: isContextLine,
+ };
+ },
trimFirstChar(line) {
if (!line.richText) {
return line;
diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js
index 321967a5479..83dc59851b9 100644
--- a/app/assets/javascripts/diffs/store/actions.js
+++ b/app/assets/javascripts/diffs/store/actions.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import VueResource from 'vue-resource';
+import axios from '~/lib/utils/axios_utils';
import Cookies from 'js-cookie';
import { handleLocationHash } from '~/lib/utils/common_utils';
import * as types from './mutation_types';
@@ -9,8 +9,6 @@ import {
DIFF_VIEW_COOKIE_NAME,
} from '../constants';
-Vue.use(VueResource);
-
export const setEndpoint = ({ commit }, endpoint) => {
commit(types.SET_ENDPOINT, endpoint);
};
@@ -22,12 +20,11 @@ export const setLoadingState = ({ commit }, state) => {
export const fetchDiffFiles = ({ state, commit }) => {
commit(types.SET_LOADING, true);
- return Vue.http
+ return axios
.get(state.endpoint)
- .then(res => res.json())
.then(res => {
commit(types.SET_LOADING, false);
- commit(types.SET_DIFF_FILES, res.diff_files);
+ commit(types.SET_DIFF_FILES, res.data.diff_files);
return Vue.nextTick();
})
.then(handleLocationHash);
@@ -47,3 +44,18 @@ export const showCommentForm = ({ commit }, params) => {
export const cancelCommentForm = ({ commit }, params) => {
commit(types.REMOVE_COMMENT_FORM_LINE, params);
};
+
+export const loadMoreLines = ({ commit }, options) => {
+ const { endpoint, params, lineNumbers, fileHash } = options;
+
+ return axios.get(endpoint, { params }).then(res => {
+ const contextLines = res.data || [];
+
+ commit(types.ADD_CONTEXT_LINES, {
+ lineNumbers,
+ contextLines,
+ params,
+ fileHash,
+ });
+ });
+};
diff --git a/app/assets/javascripts/diffs/store/mutation_types.js b/app/assets/javascripts/diffs/store/mutation_types.js
index cec771fc04e..805fa510a56 100644
--- a/app/assets/javascripts/diffs/store/mutation_types.js
+++ b/app/assets/javascripts/diffs/store/mutation_types.js
@@ -4,3 +4,4 @@ export const SET_DIFF_FILES = 'SET_DIFF_FILES';
export const SET_DIFF_VIEW_TYPE = 'SET_DIFF_VIEW_TYPE';
export const ADD_COMMENT_FORM_LINE = 'ADD_COMMENT_FORM_LINE';
export const REMOVE_COMMENT_FORM_LINE = 'REMOVE_COMMENT_FORM_LINE';
+export const ADD_CONTEXT_LINES = 'ADD_CONTEXT_LINES';
diff --git a/app/assets/javascripts/diffs/store/mutations.js b/app/assets/javascripts/diffs/store/mutations.js
index d83a966fed9..dc4bc47ae87 100644
--- a/app/assets/javascripts/diffs/store/mutations.js
+++ b/app/assets/javascripts/diffs/store/mutations.js
@@ -109,4 +109,21 @@ export default {
}
}
},
+
+ [types.ADD_CONTEXT_LINES](state, options) {
+ const { lineNumbers, contextLines, fileHash } = options;
+ const { bottom } = options.params;
+ const diffFile = utils.findDiffFile(state.diffFiles, fileHash);
+ const { highlightedDiffLines, parallelDiffLines } = diffFile;
+
+ utils.removeMatchLine(diffFile, lineNumbers, bottom);
+ const lines = utils.addLineReferences(contextLines, lineNumbers, bottom);
+ utils.addContextLines({
+ inlineLines: highlightedDiffLines,
+ parallelLines: parallelDiffLines,
+ contextLines: lines,
+ bottom,
+ lineNumbers,
+ });
+ },
};
diff --git a/app/assets/javascripts/diffs/store/utils.js b/app/assets/javascripts/diffs/store/utils.js
index 9aa44cd4fdb..f7a4eddf60d 100644
--- a/app/assets/javascripts/diffs/store/utils.js
+++ b/app/assets/javascripts/diffs/store/utils.js
@@ -1,4 +1,5 @@
import _ from 'underscore';
+import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import {
LINE_POSITION_LEFT,
LINE_POSITION_RIGHT,
@@ -6,6 +7,7 @@ import {
DIFF_NOTE_TYPE,
NEW_LINE_TYPE,
OLD_LINE_TYPE,
+ MATCH_LINE_TYPE,
} from '../constants';
export const findDiffLineIndex = options => {
@@ -26,6 +28,9 @@ export const findDiffLineIndex = options => {
});
};
+export const findDiffFile = (files, hash) =>
+ files.filter(file => file.fileHash === hash)[0];
+
export const getReversePosition = linePosition => {
if (linePosition === LINE_POSITION_RIGHT) {
return LINE_POSITION_LEFT;
@@ -81,3 +86,101 @@ export const getNoteFormData = params => {
data: postData,
};
};
+
+export const findIndexInInlineLines = (lines, lineNumbers) => {
+ const { oldLineNumber, newLineNumber } = lineNumbers;
+
+ return _.findIndex(
+ lines,
+ line => line.oldLine === oldLineNumber && line.newLine === newLineNumber,
+ );
+};
+
+export const findIndexInParallelLines = (lines, lineNumbers) => {
+ const { oldLineNumber, newLineNumber } = lineNumbers;
+
+ return _.findIndex(
+ lines,
+ line =>
+ line.left &&
+ line.right &&
+ line.left.oldLine === oldLineNumber &&
+ line.right.newLine === newLineNumber,
+ );
+};
+
+export const removeMatchLine = (diffFile, lineNumbers, bottom) => {
+ const indexForInline = findIndexInInlineLines(
+ diffFile.highlightedDiffLines,
+ lineNumbers,
+ );
+
+ const indexForParallel = findIndexInParallelLines(
+ diffFile.parallelDiffLines,
+ lineNumbers,
+ );
+
+ const factor = bottom ? 1 : -1;
+
+ diffFile.highlightedDiffLines.splice(indexForInline + factor, 1);
+ diffFile.parallelDiffLines.splice(indexForParallel + factor, 1);
+};
+
+export const addLineReferences = (lines, lineNumbers, bottom) => {
+ const { oldLineNumber, newLineNumber } = lineNumbers;
+ const lineCount = lines.length;
+ let matchLineIndex = -1;
+
+ const linesWithNumbers = lines.map((l, index) => {
+ const line = convertObjectPropsToCamelCase(l);
+
+ if (line.type === MATCH_LINE_TYPE) {
+ matchLineIndex = index;
+ } else {
+ Object.assign(line, {
+ oldLine: bottom
+ ? oldLineNumber + index + 1
+ : oldLineNumber + index - lineCount,
+ newLine: bottom
+ ? newLineNumber + index + 1
+ : newLineNumber + index - lineCount,
+ });
+ }
+
+ return line;
+ });
+
+ if (matchLineIndex > -1) {
+ const line = linesWithNumbers[matchLineIndex];
+ const targetLine = bottom
+ ? linesWithNumbers[matchLineIndex - 1]
+ : linesWithNumbers[matchLineIndex + 1];
+
+ Object.assign(line, {
+ metaData: {
+ oldPos: targetLine.oldLine,
+ newPos: targetLine.newLine,
+ },
+ });
+ }
+
+ return linesWithNumbers;
+};
+
+export const addContextLines = options => {
+ const { inlineLines, parallelLines, contextLines, lineNumbers } = options;
+ const inlineIndex = findIndexInInlineLines(inlineLines, lineNumbers);
+ const parallelIndex = findIndexInParallelLines(parallelLines, lineNumbers);
+ const normalizedParallelLines = contextLines.map(line => ({
+ left: line,
+ right: line,
+ }));
+
+ if (options.bottom) {
+ inlineLines.push(...contextLines);
+ parallelLines.push(...normalizedParallelLines);
+ } else {
+ inlineLines.splice(inlineIndex, 0, ...contextLines);
+ parallelLines.splice(parallelIndex, 0, ...normalizedParallelLines);
+ }
+};
diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js
index 2f2dc233f4c..eeda0602246 100644
--- a/app/assets/javascripts/merge_request_tabs.js
+++ b/app/assets/javascripts/merge_request_tabs.js
@@ -75,6 +75,7 @@ export default class MergeRequestTabs {
const navbar = document.querySelector('.navbar-gitlab');
const peek = document.getElementById('peek');
const paddingTop = 16;
+ this.commitsTab = document.querySelector('.tab-content .commits.tab-pane');
this.diffsLoaded = false;
this.pipelinesLoaded = false;
@@ -172,7 +173,7 @@ export default class MergeRequestTabs {
this.expandViewContainer();
}
this.destroyPipelinesView();
- $('.tab-content .commits.tab-pane').removeClass('active');
+ this.commitsTab.classList.remove('active');
} else if (action === 'pipelines') {
this.resetViewContainer();
this.mountPipelinesView();
diff --git a/app/assets/javascripts/mr_notes/index.js b/app/assets/javascripts/mr_notes/index.js
index 51600e6fdb8..c09952364f4 100644
--- a/app/assets/javascripts/mr_notes/index.js
+++ b/app/assets/javascripts/mr_notes/index.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import Vuex, { mapActions, mapGetters } from 'vuex';
+import Vuex, { mapActions, mapState } from 'vuex';
import notesApp from '../notes/components/notes_app.vue';
import diffsApp from '../diffs/components/app.vue';
import discussionCounter from '../notes/components/discussion_counter.vue';
@@ -20,7 +20,8 @@ const store = new Vuex.Store({
export default function initMrNotes() {
const mrShowNode = document.querySelector('.merge-request');
- window.mergeRequest = new MergeRequest({
+ // eslint-disable-next-line no-new
+ new MergeRequest({
action: mrShowNode.dataset.mrAction,
});
@@ -43,7 +44,9 @@ export default function initMrNotes() {
};
},
computed: {
- ...mapGetters(['activeTab']),
+ ...mapState({
+ activeTab: state => state.page.activeTab,
+ }),
},
mounted() {
this.setActiveTab(window.mrTabs.getCurrentAction());
@@ -96,7 +99,9 @@ export default function initMrNotes() {
};
},
computed: {
- ...mapGetters(['activeTab']),
+ ...mapState({
+ activeTab: state => state.page.activeTab,
+ }),
},
render(createElement) {
return createElement('diffs-app', {
diff --git a/app/assets/javascripts/mr_notes/stores/getters.js b/app/assets/javascripts/mr_notes/stores/getters.js
index c68a84ce7af..b10e9f9f9f1 100644
--- a/app/assets/javascripts/mr_notes/stores/getters.js
+++ b/app/assets/javascripts/mr_notes/stores/getters.js
@@ -1,5 +1,5 @@
export default {
- activeTab(state) {
- return state.activeTab;
+ isLoggedIn(state, getters) {
+ return !!getters.getUserData.id;
},
};
diff --git a/app/assets/javascripts/notes/components/diff_file_header.vue b/app/assets/javascripts/notes/components/diff_file_header.vue
index 362a0fe0244..7b3b7777e0a 100644
--- a/app/assets/javascripts/notes/components/diff_file_header.vue
+++ b/app/assets/javascripts/notes/components/diff_file_header.vue
@@ -56,7 +56,6 @@ export default {
this.$emit('toggleFile');
}
},
- noop() {},
truncate(sha) {
return sha.slice(0, 8);
}
diff --git a/app/assets/javascripts/notes/stores/actions.js b/app/assets/javascripts/notes/stores/actions.js
index c2ce453d34a..b2e27f6dd3f 100644
--- a/app/assets/javascripts/notes/stores/actions.js
+++ b/app/assets/javascripts/notes/stores/actions.js
@@ -140,6 +140,7 @@ export const toggleIssueLocalState = ({ commit }, newState) => {
};
export const saveNote = ({ commit, dispatch }, noteData) => {
+ // For MR discussuions we need to post as `note[note]` and issue we use `note.note`.
const note = noteData.data['note[note]'] || noteData.data.note.note;
let placeholderText = note;
const hasQuickActions = utils.hasQuickActions(placeholderText);
diff --git a/app/assets/javascripts/notes/stores/getters.js b/app/assets/javascripts/notes/stores/getters.js
index 718634595e3..82f31bee174 100644
--- a/app/assets/javascripts/notes/stores/getters.js
+++ b/app/assets/javascripts/notes/stores/getters.js
@@ -28,8 +28,8 @@ export const notesById = state =>
export const discussionsByLineCode = state =>
state.notes.reduce((acc, note) => {
- if (note.diff_discussion) {
- // For context line notes, there might be multiple notes with the same line code
+ if (note.diff_discussion && note.line_code) {
+ // For context about line notes: there might be multiple notes with the same line code
const items = acc[note.line_code] || [];
items.push(note);
diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss
index 7f037582ca0..7a94e5d27bc 100644
--- a/app/assets/stylesheets/pages/diff.scss
+++ b/app/assets/stylesheets/pages/diff.scss
@@ -71,6 +71,12 @@
span {
white-space: pre-wrap;
+
+ &.context-cell {
+ display: inline-block;
+ width: 100%;
+ height: 100%;
+ }
}
.line {
diff --git a/app/serializers/diff_file_entity.rb b/app/serializers/diff_file_entity.rb
index 13097ed4344..793a28a7beb 100644
--- a/app/serializers/diff_file_entity.rb
+++ b/app/serializers/diff_file_entity.rb
@@ -71,7 +71,7 @@ class DiffFileEntity < Grape::Entity
end
expose :context_lines_path, if: -> (diff_file, _) { diff_file.text? } do |diff_file|
- project_blob_diff_path(diff_file.repository.project, tree_join(diff_file.file_path, diff_file.content_sha))
+ project_blob_diff_path(diff_file.repository.project, tree_join(diff_file.content_sha, diff_file.file_path))
end
# Used for inline diffs