summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/diffs/store
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/diffs/store')
-rw-r--r--app/assets/javascripts/diffs/store/actions.js75
-rw-r--r--app/assets/javascripts/diffs/store/getters.js9
-rw-r--r--app/assets/javascripts/diffs/store/getters_versions_dropdowns.js31
-rw-r--r--app/assets/javascripts/diffs/store/modules/diff_state.js2
-rw-r--r--app/assets/javascripts/diffs/store/mutation_types.js2
-rw-r--r--app/assets/javascripts/diffs/store/mutations.js18
-rw-r--r--app/assets/javascripts/diffs/store/utils.js80
7 files changed, 131 insertions, 86 deletions
diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js
index d5581474c9b..0f275f1cb3e 100644
--- a/app/assets/javascripts/diffs/store/actions.js
+++ b/app/assets/javascripts/diffs/store/actions.js
@@ -52,7 +52,6 @@ export const setBaseConfig = ({ commit }, options) => {
projectPath,
dismissEndpoint,
showSuggestPopover,
- useSingleDiffStyle,
} = options;
commit(types.SET_BASE_CONFIG, {
endpoint,
@@ -62,61 +61,18 @@ export const setBaseConfig = ({ commit }, options) => {
projectPath,
dismissEndpoint,
showSuggestPopover,
- useSingleDiffStyle,
});
};
-export const fetchDiffFiles = ({ state, commit }) => {
- const worker = new TreeWorker();
- const urlParams = {
- w: state.showWhitespace ? '0' : '1',
- };
- let returnData;
-
- if (state.useSingleDiffStyle) {
- urlParams.view = state.diffViewType;
- }
-
- commit(types.SET_LOADING, true);
-
- worker.addEventListener('message', ({ data }) => {
- commit(types.SET_TREE_DATA, data);
-
- worker.terminate();
- });
-
- return axios
- .get(mergeUrlParams(urlParams, state.endpoint))
- .then(res => {
- commit(types.SET_LOADING, false);
-
- commit(types.SET_MERGE_REQUEST_DIFFS, res.data.merge_request_diffs || []);
- commit(types.SET_DIFF_DATA, res.data);
-
- worker.postMessage(state.diffFiles);
-
- returnData = res.data;
- return Vue.nextTick();
- })
- .then(() => {
- handleLocationHash();
- return returnData;
- })
- .catch(() => worker.terminate());
-};
-
export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => {
const id = window?.location?.hash;
const isNoteLink = id.indexOf('#note') === 0;
const urlParams = {
per_page: DIFFS_PER_PAGE,
w: state.showWhitespace ? '0' : '1',
+ view: window.gon?.features?.unifiedDiffLines ? 'inline' : state.diffViewType,
};
- if (state.useSingleDiffStyle) {
- urlParams.view = state.diffViewType;
- }
-
commit(types.SET_BATCH_LOADING, true);
commit(types.SET_RETRIEVING_BATCHES, true);
@@ -128,7 +84,7 @@ export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => {
commit(types.SET_BATCH_LOADING, false);
if (!isNoteLink && !state.currentDiffFileId) {
- commit(types.UPDATE_CURRENT_DIFF_FILE_ID, diff_files[0].file_hash);
+ commit(types.VIEW_DIFF_FILE, diff_files[0].file_hash);
}
if (isNoteLink) {
@@ -144,7 +100,7 @@ export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => {
!state.diffFiles.some(f => f.file_hash === state.currentDiffFileId) &&
!isNoteLink
) {
- commit(types.UPDATE_CURRENT_DIFF_FILE_ID, state.diffFiles[0].file_hash);
+ commit(types.VIEW_DIFF_FILE, state.diffFiles[0].file_hash);
}
if (gon.features?.codeNavigation) {
@@ -175,11 +131,9 @@ export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => {
export const fetchDiffFilesMeta = ({ commit, state }) => {
const worker = new TreeWorker();
- const urlParams = {};
-
- if (state.useSingleDiffStyle) {
- urlParams.view = state.diffViewType;
- }
+ const urlParams = {
+ view: window.gon?.features?.unifiedDiffLines ? 'inline' : state.diffViewType,
+ };
commit(types.SET_LOADING, true);
@@ -229,7 +183,7 @@ export const fetchCoverageFiles = ({ commit, state }) => {
export const setHighlightedRow = ({ commit }, lineCode) => {
const fileHash = lineCode.split('_')[0];
commit(types.SET_HIGHLIGHTED_ROW, lineCode);
- commit(types.UPDATE_CURRENT_DIFF_FILE_ID, fileHash);
+ commit(types.VIEW_DIFF_FILE, fileHash);
};
// This is adding line discussions to the actual lines in the diff tree
@@ -240,10 +194,7 @@ export const assignDiscussionsToDiff = (
) => {
const id = window?.location?.hash;
const isNoteLink = id.indexOf('#note') === 0;
- const diffPositionByLineCode = getDiffPositionByLineCode(
- state.diffFiles,
- state.useSingleDiffStyle,
- );
+ const diffPositionByLineCode = getDiffPositionByLineCode(state.diffFiles);
const hash = getLocationHash();
discussions
@@ -477,13 +428,17 @@ export const toggleTreeOpen = ({ commit }, path) => {
commit(types.TOGGLE_FOLDER_OPEN, path);
};
+export const toggleActiveFileByHash = ({ commit }, hash) => {
+ commit(types.VIEW_DIFF_FILE, hash);
+};
+
export const scrollToFile = ({ state, commit }, path) => {
if (!state.treeEntries[path]) return;
const { fileHash } = state.treeEntries[path];
document.location.hash = fileHash;
- commit(types.UPDATE_CURRENT_DIFF_FILE_ID, fileHash);
+ commit(types.VIEW_DIFF_FILE, fileHash);
};
export const toggleShowTreeList = ({ commit, state }, saving = true) => {
@@ -751,7 +706,7 @@ export const setCurrentDiffFileIdFromNote = ({ commit, state, rootGetters }, not
const fileHash = rootGetters.getDiscussion(note.discussion_id).diff_file?.file_hash;
if (fileHash && state.diffFiles.some(f => f.file_hash === fileHash)) {
- commit(types.UPDATE_CURRENT_DIFF_FILE_ID, fileHash);
+ commit(types.VIEW_DIFF_FILE, fileHash);
}
};
@@ -759,5 +714,5 @@ export const navigateToDiffFileIndex = ({ commit, state }, index) => {
const fileHash = state.diffFiles[index].file_hash;
document.location.hash = fileHash;
- commit(types.UPDATE_CURRENT_DIFF_FILE_ID, fileHash);
+ commit(types.VIEW_DIFF_FILE, fileHash);
};
diff --git a/app/assets/javascripts/diffs/store/getters.js b/app/assets/javascripts/diffs/store/getters.js
index a24894b8d6b..42df5873a41 100644
--- a/app/assets/javascripts/diffs/store/getters.js
+++ b/app/assets/javascripts/diffs/store/getters.js
@@ -1,4 +1,5 @@
import { __, n__ } from '~/locale';
+import { parallelizeDiffLines } from './utils';
import { PARALLEL_DIFF_VIEW_TYPE, INLINE_DIFF_VIEW_TYPE } from '../constants';
export * from './getters_versions_dropdowns';
@@ -129,3 +130,11 @@ export const fileLineCoverage = state => (file, line) => {
*/
export const currentDiffIndex = state =>
Math.max(0, state.diffFiles.findIndex(diff => diff.file_hash === state.currentDiffFileId));
+
+export const diffLines = state => file => {
+ if (state.diffViewType === INLINE_DIFF_VIEW_TYPE) {
+ return null;
+ }
+
+ return parallelizeDiffLines(file.highlighted_diff_lines || []);
+};
diff --git a/app/assets/javascripts/diffs/store/getters_versions_dropdowns.js b/app/assets/javascripts/diffs/store/getters_versions_dropdowns.js
index 1e8e736c028..135b1c61ef5 100644
--- a/app/assets/javascripts/diffs/store/getters_versions_dropdowns.js
+++ b/app/assets/javascripts/diffs/store/getters_versions_dropdowns.js
@@ -11,17 +11,26 @@ export const diffCompareDropdownTargetVersions = (state, getters) => {
// startVersion only exists if the user has selected a version other
// than "base" so if startVersion is null then base must be selected
- const diffHead = parseBoolean(getParameterByName('diff_head'));
+ const defaultMergeRefForDiffs = window.gon?.features?.defaultMergeRefForDiffs || false;
+ const diffHeadParam = getParameterByName('diff_head');
+ const diffHead = parseBoolean(diffHeadParam) || (!diffHeadParam && defaultMergeRefForDiffs);
const isBaseSelected = !state.startVersion && !diffHead;
const isHeadSelected = !state.startVersion && diffHead;
+ let baseVersion = null;
- const baseVersion = {
- versionName: state.targetBranchName,
- version_index: DIFF_COMPARE_BASE_VERSION_INDEX,
- href: state.mergeRequestDiff.base_version_path,
- isBase: true,
- selected: isBaseSelected,
- };
+ if (
+ !defaultMergeRefForDiffs ||
+ (defaultMergeRefForDiffs && !state.mergeRequestDiff.head_version_path)
+ ) {
+ baseVersion = {
+ versionName: state.targetBranchName,
+ version_index: DIFF_COMPARE_BASE_VERSION_INDEX,
+ href: state.mergeRequestDiff.base_version_path,
+ isBase: true,
+ selected:
+ isBaseSelected || (defaultMergeRefForDiffs && !state.mergeRequestDiff.head_version_path),
+ };
+ }
const headVersion = {
versionName: state.targetBranchName,
@@ -40,7 +49,11 @@ export const diffCompareDropdownTargetVersions = (state, getters) => {
};
};
- return [...state.mergeRequestDiffs.slice(1).map(formatVersion), baseVersion, headVersion];
+ return [
+ ...state.mergeRequestDiffs.slice(1).map(formatVersion),
+ baseVersion,
+ state.mergeRequestDiff.head_version_path && headVersion,
+ ].filter(a => a);
};
export const diffCompareDropdownSourceVersions = (state, getters) => {
diff --git a/app/assets/javascripts/diffs/store/modules/diff_state.js b/app/assets/javascripts/diffs/store/modules/diff_state.js
index d31a600e354..001d9d9f594 100644
--- a/app/assets/javascripts/diffs/store/modules/diff_state.js
+++ b/app/assets/javascripts/diffs/store/modules/diff_state.js
@@ -34,6 +34,7 @@ export default () => ({
showTreeList: true,
currentDiffFileId: '',
projectPath: '',
+ viewedDiffFileIds: {},
commentForms: [],
highlightedRow: null,
renderTreeList: true,
@@ -41,5 +42,4 @@ export default () => ({
fileFinderVisible: false,
dismissEndpoint: '',
showSuggestPopover: true,
- useSingleDiffStyle: false,
});
diff --git a/app/assets/javascripts/diffs/store/mutation_types.js b/app/assets/javascripts/diffs/store/mutation_types.js
index 4b1dbc34902..5dba2e9d10d 100644
--- a/app/assets/javascripts/diffs/store/mutation_types.js
+++ b/app/assets/javascripts/diffs/store/mutation_types.js
@@ -19,7 +19,7 @@ export const SET_LINE_DISCUSSIONS_FOR_FILE = 'SET_LINE_DISCUSSIONS_FOR_FILE';
export const REMOVE_LINE_DISCUSSIONS_FOR_FILE = 'REMOVE_LINE_DISCUSSIONS_FOR_FILE';
export const TOGGLE_FOLDER_OPEN = 'TOGGLE_FOLDER_OPEN';
export const TOGGLE_SHOW_TREE_LIST = 'TOGGLE_SHOW_TREE_LIST';
-export const UPDATE_CURRENT_DIFF_FILE_ID = 'UPDATE_CURRENT_DIFF_FILE_ID';
+export const VIEW_DIFF_FILE = 'VIEW_DIFF_FILE';
export const OPEN_DIFF_FILE_COMMENT_FORM = 'OPEN_DIFF_FILE_COMMENT_FORM';
export const UPDATE_DIFF_FILE_COMMENT_FORM = 'UPDATE_DIFF_FILE_COMMENT_FORM';
diff --git a/app/assets/javascripts/diffs/store/mutations.js b/app/assets/javascripts/diffs/store/mutations.js
index 0d41f1c2178..7925c620c4e 100644
--- a/app/assets/javascripts/diffs/store/mutations.js
+++ b/app/assets/javascripts/diffs/store/mutations.js
@@ -1,4 +1,6 @@
+import Vue from 'vue';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
+import { INLINE_DIFF_VIEW_TYPE } from '../constants';
import {
findDiffFile,
addLineReferences,
@@ -24,7 +26,6 @@ export default {
projectPath,
dismissEndpoint,
showSuggestPopover,
- useSingleDiffStyle,
} = options;
Object.assign(state, {
endpoint,
@@ -34,7 +35,6 @@ export default {
projectPath,
dismissEndpoint,
showSuggestPopover,
- useSingleDiffStyle,
});
},
@@ -57,10 +57,7 @@ export default {
[types.SET_DIFF_DATA](state, data) {
let files = state.diffFiles;
- if (
- !(gon?.features?.diffsBatchLoad && window.location.search.indexOf('diff_id') === -1) &&
- data.diff_files
- ) {
+ if (window.location.search.indexOf('diff_id') !== -1 && data.diff_files) {
files = prepareDiffData(data, files);
}
@@ -154,7 +151,9 @@ export default {
addContextLines({
inlineLines: diffFile.highlighted_diff_lines,
parallelLines: diffFile.parallel_diff_lines,
- diffViewType: state.diffViewType,
+ diffViewType: window.gon?.features?.unifiedDiffLines
+ ? INLINE_DIFF_VIEW_TYPE
+ : state.diffViewType,
contextLines: lines,
bottom,
lineNumbers,
@@ -249,7 +248,7 @@ export default {
});
}
- if (!file.parallel_diff_lines || !file.highlighted_diff_lines) {
+ if (!file.parallel_diff_lines.length || !file.highlighted_diff_lines.length) {
const newDiscussions = (file.discussions || [])
.filter(d => d.id !== discussion.id)
.concat(discussion);
@@ -293,8 +292,9 @@ export default {
[types.TOGGLE_SHOW_TREE_LIST](state) {
state.showTreeList = !state.showTreeList;
},
- [types.UPDATE_CURRENT_DIFF_FILE_ID](state, fileId) {
+ [types.VIEW_DIFF_FILE](state, fileId) {
state.currentDiffFileId = fileId;
+ Vue.set(state.viewedDiffFileIds, fileId, true);
},
[types.OPEN_DIFF_FILE_COMMENT_FORM](state, formData) {
state.commentForms.push({
diff --git a/app/assets/javascripts/diffs/store/utils.js b/app/assets/javascripts/diffs/store/utils.js
index f014cddda32..69330ffae2f 100644
--- a/app/assets/javascripts/diffs/store/utils.js
+++ b/app/assets/javascripts/diffs/store/utils.js
@@ -11,7 +11,6 @@ import {
OLD_LINE_TYPE,
MATCH_LINE_TYPE,
LINES_TO_BE_RENDERED_DIRECTLY,
- MAX_LINES_TO_BE_RENDERED,
TREE_TYPE,
INLINE_DIFF_VIEW_TYPE,
PARALLEL_DIFF_VIEW_TYPE,
@@ -20,6 +19,77 @@ import {
} from '../constants';
import { prepareRawDiffFile } from '../diff_file';
+export const isAdded = line => ['new', 'new-nonewline'].includes(line.type);
+export const isRemoved = line => ['old', 'old-nonewline'].includes(line.type);
+export const isUnchanged = line => !line.type;
+export const isMeta = line => ['match', 'new-nonewline', 'old-nonewline'].includes(line.type);
+
+/**
+ * Pass in the inline diff lines array which gets converted
+ * to the parallel diff lines.
+ * This allows for us to convert inline diff lines to parallel
+ * on the frontend without needing to send any requests
+ * to the API.
+ *
+ * This method has been taken from the already existing backend
+ * implementation at lib/gitlab/diff/parallel_diff.rb
+ *
+ * @param {Object[]} diffLines - inline diff lines
+ *
+ * @returns {Object[]} parallel lines
+ */
+export const parallelizeDiffLines = (diffLines = []) => {
+ let freeRightIndex = null;
+ const lines = [];
+
+ for (let i = 0, diffLinesLength = diffLines.length, index = 0; i < diffLinesLength; i += 1) {
+ const line = diffLines[i];
+
+ if (isRemoved(line)) {
+ lines.push({
+ [LINE_POSITION_LEFT]: line,
+ [LINE_POSITION_RIGHT]: null,
+ });
+
+ if (freeRightIndex === null) {
+ // Once we come upon a new line it can be put on the right of this old line
+ freeRightIndex = index;
+ }
+ index += 1;
+ } else if (isAdded(line)) {
+ if (freeRightIndex !== null) {
+ // If an old line came before this without a line on the right, this
+ // line can be put to the right of it.
+ lines[freeRightIndex].right = line;
+
+ // If there are any other old lines on the left that don't yet have
+ // a new counterpart on the right, update the free_right_index
+ const nextFreeRightIndex = freeRightIndex + 1;
+ freeRightIndex = nextFreeRightIndex < index ? nextFreeRightIndex : null;
+ } else {
+ lines.push({
+ [LINE_POSITION_LEFT]: null,
+ [LINE_POSITION_RIGHT]: line,
+ });
+
+ freeRightIndex = null;
+ index += 1;
+ }
+ } else if (isMeta(line) || isUnchanged(line)) {
+ // line in the right panel is the same as in the left one
+ lines.push({
+ [LINE_POSITION_LEFT]: line,
+ [LINE_POSITION_RIGHT]: line,
+ });
+
+ freeRightIndex = null;
+ index += 1;
+ }
+ }
+
+ return lines;
+};
+
export function findDiffFile(files, match, matchKey = 'file_hash') {
return files.find(file => file[matchKey] === match);
}
@@ -281,7 +351,7 @@ function mergeTwoFiles(target, source) {
function ensureBasicDiffFileLines(file) {
const missingInline = !file.highlighted_diff_lines;
- const missingParallel = !file.parallel_diff_lines;
+ const missingParallel = !file.parallel_diff_lines || window.gon?.features?.unifiedDiffLines;
Object.assign(file, {
highlighted_diff_lines: missingInline ? [] : file.highlighted_diff_lines,
@@ -379,12 +449,10 @@ function getVisibleDiffLines(file) {
}
function finalizeDiffFile(file) {
- const name = (file.viewer && file.viewer.name) || diffViewerModes.text;
const lines = getVisibleDiffLines(file);
Object.assign(file, {
renderIt: lines < LINES_TO_BE_RENDERED_DIRECTLY,
- collapsed: name === diffViewerModes.text && lines > MAX_LINES_TO_BE_RENDERED,
isShowingFullFile: false,
isLoadingFullFile: false,
discussions: [],
@@ -417,11 +485,11 @@ export function prepareDiffData(diff, priorFiles = []) {
return deduplicateFilesList([...priorFiles, ...cleanedFiles]);
}
-export function getDiffPositionByLineCode(diffFiles, useSingleDiffStyle) {
+export function getDiffPositionByLineCode(diffFiles) {
let lines = [];
const hasInlineDiffs = diffFiles.some(file => file.highlighted_diff_lines.length > 0);
- if (!useSingleDiffStyle || hasInlineDiffs) {
+ if (hasInlineDiffs) {
// In either of these cases, we can use `highlighted_diff_lines` because
// that will include all of the parallel diff lines, too