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.js65
-rw-r--r--app/assets/javascripts/diffs/store/getters.js68
-rw-r--r--app/assets/javascripts/diffs/store/getters_versions_dropdowns.js28
-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.js57
-rw-r--r--app/assets/javascripts/diffs/store/utils.js97
7 files changed, 197 insertions, 122 deletions
diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js
index 5b410051705..e95e9ac3ee4 100644
--- a/app/assets/javascripts/diffs/store/actions.js
+++ b/app/assets/javascripts/diffs/store/actions.js
@@ -50,6 +50,8 @@ import {
} from '../constants';
import { diffViewerModes } from '~/ide/constants';
import { isCollapsed } from '../utils/diff_file';
+import { getDerivedMergeRequestInformation } from '../utils/merge_request';
+import { markFileReview, setReviewsForMergeRequest } from '../utils/file_reviews';
export const setBaseConfig = ({ commit }, options) => {
const {
@@ -60,7 +62,9 @@ export const setBaseConfig = ({ commit }, options) => {
projectPath,
dismissEndpoint,
showSuggestPopover,
+ defaultSuggestionCommitMessage,
viewDiffsFileByFile,
+ mrReviews,
} = options;
commit(types.SET_BASE_CONFIG, {
endpoint,
@@ -70,7 +74,9 @@ export const setBaseConfig = ({ commit }, options) => {
projectPath,
dismissEndpoint,
showSuggestPopover,
+ defaultSuggestionCommitMessage,
viewDiffsFileByFile,
+ mrReviews,
});
};
@@ -123,7 +129,7 @@ export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => {
// We need to check that the currentDiffFileId points to a file that exists
if (
state.currentDiffFileId &&
- !state.diffFiles.some(f => f.file_hash === state.currentDiffFileId) &&
+ !state.diffFiles.some((f) => f.file_hash === state.currentDiffFileId) &&
!isNoteLink
) {
commit(types.VIEW_DIFF_FILE, state.diffFiles[0].file_hash);
@@ -131,11 +137,11 @@ export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => {
if (state.diffFiles?.length) {
// eslint-disable-next-line promise/catch-or-return,promise/no-nesting
- import('~/code_navigation').then(m =>
+ import('~/code_navigation').then((m) =>
m.default({
blobs: state.diffFiles
- .filter(f => f.code_navigation_path)
- .map(f => ({
+ .filter((f) => f.code_navigation_path)
+ .map((f) => ({
path: f.new_path,
codeNavigationPath: f.code_navigation_path,
})),
@@ -157,7 +163,7 @@ export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => {
return pagination.next_page;
})
- .then(nextPage => nextPage && getBatch(nextPage))
+ .then((nextPage) => nextPage && getBatch(nextPage))
.catch(() => commit(types.SET_RETRIEVING_BATCHES, false));
return getBatch()
@@ -207,7 +213,7 @@ export const fetchDiffFilesMeta = ({ commit, state }) => {
export const fetchCoverageFiles = ({ commit, state }) => {
const coveragePoll = new Poll({
resource: {
- getCoverageReports: endpoint => axios.get(endpoint),
+ getCoverageReports: (endpoint) => axios.get(endpoint),
},
data: state.endpointCoverage,
method: 'getCoverageReports',
@@ -242,8 +248,8 @@ export const assignDiscussionsToDiff = (
const hash = getLocationHash();
discussions
- .filter(discussion => discussion.diff_discussion)
- .forEach(discussion => {
+ .filter((discussion) => discussion.diff_discussion)
+ .forEach((discussion) => {
commit(types.SET_LINE_DISCUSSIONS_FOR_FILE, {
discussion,
diffPositionByLineCode,
@@ -270,10 +276,10 @@ export const toggleLineDiscussions = ({ commit }, options) => {
};
export const renderFileForDiscussionId = ({ commit, rootState, state }, discussionId) => {
- const discussion = rootState.notes.discussions.find(d => d.id === discussionId);
+ const discussion = rootState.notes.discussions.find((d) => d.id === discussionId);
if (discussion && discussion.diff_file) {
- const file = state.diffFiles.find(f => f.file_hash === discussion.diff_file.file_hash);
+ const file = state.diffFiles.find((f) => f.file_hash === discussion.diff_file.file_hash);
if (file) {
if (!file.renderIt) {
@@ -299,11 +305,12 @@ export const renderFileForDiscussionId = ({ commit, rootState, state }, discussi
export const startRenderDiffsQueue = ({ state, commit }) => {
const checkItem = () =>
- new Promise(resolve => {
+ new Promise((resolve) => {
const nextFile = state.diffFiles.find(
- file =>
+ (file) =>
!file.renderIt &&
- (file.viewer && (!isCollapsed(file) || file.viewer.name !== diffViewerModes.text)),
+ file.viewer &&
+ (!isCollapsed(file) || file.viewer.name !== diffViewerModes.text),
);
if (nextFile) {
@@ -357,7 +364,7 @@ export const loadMoreLines = ({ commit }, options) => {
params.from_merge_request = true;
- return axios.get(endpoint, { params }).then(res => {
+ return axios.get(endpoint, { params }).then((res) => {
const contextLines = res.data || [];
commit(types.ADD_CONTEXT_LINES, {
@@ -398,7 +405,7 @@ export const loadCollapsedDiff = ({ commit, getters, state }, file) =>
w: state.showWhitespace ? '0' : '1',
},
})
- .then(res => {
+ .then((res) => {
commit(types.ADD_COLLAPSED_DIFFS, {
file,
data: res.data,
@@ -421,7 +428,7 @@ export const toggleFileDiscussions = ({ getters, dispatch }, diff) => {
const shouldCloseAll = getters.diffHasAllExpandedDiscussions(diff);
const shouldExpandAll = getters.diffHasAllCollapsedDiscussions(diff);
- discussions.forEach(discussion => {
+ discussions.forEach((discussion) => {
const data = { discussionId: discussion.id };
if (shouldCloseAll) {
@@ -435,13 +442,13 @@ export const toggleFileDiscussions = ({ getters, dispatch }, diff) => {
export const toggleFileDiscussionWrappers = ({ commit }, diff) => {
const discussionWrappersExpanded = allDiscussionWrappersExpanded(diff);
const lineCodesWithDiscussions = new Set();
- const lineHasDiscussion = line => Boolean(line?.discussions.length);
- const registerDiscussionLine = line => lineCodesWithDiscussions.add(line.line_code);
+ const lineHasDiscussion = (line) => Boolean(line?.discussions.length);
+ const registerDiscussionLine = (line) => lineCodesWithDiscussions.add(line.line_code);
diff[INLINE_DIFF_LINES_KEY].filter(lineHasDiscussion).forEach(registerDiscussionLine);
if (lineCodesWithDiscussions.size) {
- Array.from(lineCodesWithDiscussions).forEach(lineCode => {
+ Array.from(lineCodesWithDiscussions).forEach((lineCode) => {
commit(types.TOGGLE_LINE_DISCUSSIONS, {
fileHash: diff.file_hash,
expanded: !discussionWrappersExpanded,
@@ -459,8 +466,8 @@ export const saveDiffDiscussion = ({ state, dispatch }, { note, formData }) => {
});
return dispatch('saveNote', postData, { root: true })
- .then(result => dispatch('updateDiscussion', result.discussion, { root: true }))
- .then(discussion => dispatch('assignDiscussionsToDiff', [discussion]))
+ .then((result) => dispatch('updateDiscussion', result.discussion, { root: true }))
+ .then((discussion) => dispatch('assignDiscussionsToDiff', [discussion]))
.then(() => dispatch('updateResolvableDiscussionsCounts', null, { root: true }))
.then(() => dispatch('closeDiffFileCommentForm', formData.diffFile.file_hash))
.catch(() => createFlash(s__('MergeRequests|Saving the comment failed')));
@@ -560,7 +567,7 @@ export const setExpandedDiffLines = ({ commit }, { file, data }) => {
});
commit(types.TOGGLE_DIFF_FILE_RENDERING_MORE, file.file_path);
- const idleCb = t => {
+ const idleCb = (t) => {
const startIndex = index;
while (
@@ -608,7 +615,7 @@ export const fetchFullDiff = ({ commit, dispatch }, file) =>
.catch(() => dispatch('receiveFullDiffError', file.file_path));
export const toggleFullDiff = ({ dispatch, commit, getters, state }, filePath) => {
- const file = state.diffFiles.find(f => f.file_path === filePath);
+ const file = state.diffFiles.find((f) => f.file_path === filePath);
commit(types.REQUEST_FULL_DIFF, filePath);
@@ -719,7 +726,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)) {
+ if (fileHash && state.diffFiles.some((f) => f.file_hash === fileHash)) {
commit(types.VIEW_DIFF_FILE, fileHash);
}
};
@@ -741,3 +748,13 @@ export const setFileByFile = ({ commit }, { fileByFile }) => {
mergeUrlParams({ [DIFF_FILE_BY_FILE_COOKIE_NAME]: fileViewMode }, window.location.href),
);
};
+
+export function reviewFile({ commit, state, getters }, { file, reviewed = true }) {
+ const { mrPath } = getDerivedMergeRequestInformation({ endpoint: file.load_collapsed_diff_url });
+ const reviews = setReviewsForMergeRequest(
+ mrPath,
+ markFileReview(getters.fileReviews(state), file, reviewed),
+ );
+
+ commit(types.SET_MR_FILE_REVIEWS, reviews);
+}
diff --git a/app/assets/javascripts/diffs/store/getters.js b/app/assets/javascripts/diffs/store/getters.js
index baf54188932..a167b6d4694 100644
--- a/app/assets/javascripts/diffs/store/getters.js
+++ b/app/assets/javascripts/diffs/store/getters.js
@@ -1,5 +1,6 @@
import { __, n__ } from '~/locale';
import { parallelizeDiffLines } from './utils';
+import { isFileReviewed } from '../utils/file_reviews';
import {
PARALLEL_DIFF_VIEW_TYPE,
INLINE_DIFF_VIEW_TYPE,
@@ -8,13 +9,13 @@ import {
export * from './getters_versions_dropdowns';
-export const isParallelView = state => state.diffViewType === PARALLEL_DIFF_VIEW_TYPE;
+export const isParallelView = (state) => state.diffViewType === PARALLEL_DIFF_VIEW_TYPE;
-export const isInlineView = state => state.diffViewType === INLINE_DIFF_VIEW_TYPE;
+export const isInlineView = (state) => state.diffViewType === INLINE_DIFF_VIEW_TYPE;
-export const whichCollapsedTypes = state => {
- const automatic = state.diffFiles.some(file => file.viewer?.automaticallyCollapsed);
- const manual = state.diffFiles.some(file => file.viewer?.manuallyCollapsed);
+export const whichCollapsedTypes = (state) => {
+ const automatic = state.diffFiles.some((file) => file.viewer?.automaticallyCollapsed);
+ const manual = state.diffFiles.some((file) => file.viewer?.manuallyCollapsed);
return {
any: automatic || manual,
@@ -23,18 +24,18 @@ export const whichCollapsedTypes = state => {
};
};
-export const commitId = state => (state.commit && state.commit.id ? state.commit.id : null);
+export const commitId = (state) => (state.commit && state.commit.id ? state.commit.id : null);
/**
* Checks if the diff has all discussions expanded
* @param {Object} diff
* @returns {Boolean}
*/
-export const diffHasAllExpandedDiscussions = (state, getters) => diff => {
+export const diffHasAllExpandedDiscussions = (state, getters) => (diff) => {
const discussions = getters.getDiffFileDiscussions(diff);
return (
- (discussions && discussions.length && discussions.every(discussion => discussion.expanded)) ||
+ (discussions && discussions.length && discussions.every((discussion) => discussion.expanded)) ||
false
);
};
@@ -44,11 +45,13 @@ export const diffHasAllExpandedDiscussions = (state, getters) => diff => {
* @param {Object} diff
* @returns {Boolean}
*/
-export const diffHasAllCollapsedDiscussions = (state, getters) => diff => {
+export const diffHasAllCollapsedDiscussions = (state, getters) => (diff) => {
const discussions = getters.getDiffFileDiscussions(diff);
return (
- (discussions && discussions.length && discussions.every(discussion => !discussion.expanded)) ||
+ (discussions &&
+ discussions.length &&
+ discussions.every((discussion) => !discussion.expanded)) ||
false
);
};
@@ -58,9 +61,9 @@ export const diffHasAllCollapsedDiscussions = (state, getters) => diff => {
* @param {Object} diff
* @returns {Boolean}
*/
-export const diffHasExpandedDiscussions = () => diff => {
- return diff[INLINE_DIFF_LINES_KEY].filter(l => l.discussions.length >= 1).some(
- l => l.discussionsExpanded,
+export const diffHasExpandedDiscussions = () => (diff) => {
+ return diff[INLINE_DIFF_LINES_KEY].filter((l) => l.discussions.length >= 1).some(
+ (l) => l.discussionsExpanded,
);
};
@@ -69,8 +72,8 @@ export const diffHasExpandedDiscussions = () => diff => {
* @param {Boolean} diff
* @returns {Boolean}
*/
-export const diffHasDiscussions = () => diff => {
- return diff[INLINE_DIFF_LINES_KEY].some(l => l.discussions.length >= 1);
+export const diffHasDiscussions = () => (diff) => {
+ return diff[INLINE_DIFF_LINES_KEY].some((l) => l.discussions.length >= 1);
};
/**
@@ -78,22 +81,22 @@ export const diffHasDiscussions = () => diff => {
* @param {Object} diff
* @returns {Array}
*/
-export const getDiffFileDiscussions = (state, getters, rootState, rootGetters) => diff =>
+export const getDiffFileDiscussions = (state, getters, rootState, rootGetters) => (diff) =>
rootGetters.discussions.filter(
- discussion => discussion.diff_discussion && discussion.diff_file.file_hash === diff.file_hash,
+ (discussion) => discussion.diff_discussion && discussion.diff_file.file_hash === diff.file_hash,
) || [];
-export const getDiffFileByHash = state => fileHash =>
- state.diffFiles.find(file => file.file_hash === fileHash);
+export const getDiffFileByHash = (state) => (fileHash) =>
+ state.diffFiles.find((file) => file.file_hash === fileHash);
-export const flatBlobsList = state =>
- Object.values(state.treeEntries).filter(f => f.type === 'blob');
+export const flatBlobsList = (state) =>
+ Object.values(state.treeEntries).filter((f) => f.type === 'blob');
export const allBlobs = (state, getters) =>
getters.flatBlobsList.reduce((acc, file) => {
const { parentPath } = file;
- if (parentPath && !acc.some(f => f.path === parentPath)) {
+ if (parentPath && !acc.some((f) => f.path === parentPath)) {
acc.push({
path: parentPath,
isHeader: true,
@@ -101,13 +104,13 @@ export const allBlobs = (state, getters) =>
});
}
- acc.find(f => f.path === parentPath).tree.push(file);
+ acc.find((f) => f.path === parentPath).tree.push(file);
return acc;
}, []);
-export const getCommentFormForDiffFile = state => fileHash =>
- state.commentForms.find(form => form.fileHash === fileHash);
+export const getCommentFormForDiffFile = (state) => (fileHash) =>
+ state.commentForms.find((form) => form.fileHash === fileHash);
/**
* Returns the test coverage hits for a specific line of a given file
@@ -115,7 +118,7 @@ export const getCommentFormForDiffFile = state => fileHash =>
* @param {number} line
* @returns {number}
*/
-export const fileLineCoverage = state => (file, line) => {
+export const fileLineCoverage = (state) => (file, line) => {
if (!state.coverageFiles.files) return {};
const fileCoverage = state.coverageFiles.files[file];
if (!fileCoverage) return {};
@@ -136,10 +139,13 @@ export const fileLineCoverage = state => (file, line) => {
* Returns index of a currently selected diff in diffFiles
* @returns {number}
*/
-export const currentDiffIndex = state =>
- Math.max(0, state.diffFiles.findIndex(diff => diff.file_hash === state.currentDiffFileId));
+export const currentDiffIndex = (state) =>
+ Math.max(
+ 0,
+ state.diffFiles.findIndex((diff) => diff.file_hash === state.currentDiffFileId),
+ );
-export const diffLines = state => (file, unifiedDiffComponents) => {
+export const diffLines = (state) => (file, unifiedDiffComponents) => {
if (!unifiedDiffComponents && state.diffViewType === INLINE_DIFF_VIEW_TYPE) {
return null;
}
@@ -149,3 +155,7 @@ export const diffLines = state => (file, unifiedDiffComponents) => {
state.diffViewType === INLINE_DIFF_VIEW_TYPE,
);
};
+
+export function fileReviews(state) {
+ return state.diffFiles.map((file) => isFileReviewed(state.mrReviews, file));
+}
diff --git a/app/assets/javascripts/diffs/store/getters_versions_dropdowns.js b/app/assets/javascripts/diffs/store/getters_versions_dropdowns.js
index 135b1c61ef5..3f33b0c900e 100644
--- a/app/assets/javascripts/diffs/store/getters_versions_dropdowns.js
+++ b/app/assets/javascripts/diffs/store/getters_versions_dropdowns.js
@@ -2,10 +2,10 @@ import { __, n__, sprintf } from '~/locale';
import { getParameterByName, parseBoolean } from '~/lib/utils/common_utils';
import { DIFF_COMPARE_BASE_VERSION_INDEX, DIFF_COMPARE_HEAD_VERSION_INDEX } from '../constants';
-export const selectedTargetIndex = state =>
+export const selectedTargetIndex = (state) =>
state.startVersion?.version_index || DIFF_COMPARE_BASE_VERSION_INDEX;
-export const selectedSourceIndex = state => state.mergeRequestDiff.version_index;
+export const selectedSourceIndex = (state) => state.mergeRequestDiff.version_index;
export const diffCompareDropdownTargetVersions = (state, getters) => {
// startVersion only exists if the user has selected a version other
@@ -40,7 +40,7 @@ export const diffCompareDropdownTargetVersions = (state, getters) => {
selected: isHeadSelected,
};
// Appended properties here are to make the compare_dropdown_layout easier to reason about
- const formatVersion = v => {
+ const formatVersion = (v) => {
return {
href: v.compare_path,
versionName: sprintf(__(`version %{versionIndex}`), { versionIndex: v.version_index }),
@@ -53,19 +53,23 @@ export const diffCompareDropdownTargetVersions = (state, getters) => {
...state.mergeRequestDiffs.slice(1).map(formatVersion),
baseVersion,
state.mergeRequestDiff.head_version_path && headVersion,
- ].filter(a => a);
+ ].filter((a) => a);
};
export const diffCompareDropdownSourceVersions = (state, getters) => {
// Appended properties here are to make the compare_dropdown_layout easier to reason about
- return state.mergeRequestDiffs.map((v, i) => ({
- ...v,
- href: v.version_path,
- commitsText: n__(`%d commit,`, `%d commits,`, v.commits_count),
- versionName:
- i === 0
+ return state.mergeRequestDiffs.map((v, i) => {
+ const isLatestVersion = i === 0;
+
+ return {
+ ...v,
+ href: v.version_path,
+ commitsText: n__(`%d commit,`, `%d commits,`, v.commits_count),
+ isLatestVersion,
+ versionName: isLatestVersion
? __('latest version')
: sprintf(__(`version %{versionIndex}`), { versionIndex: v.version_index }),
- selected: v.version_index === getters.selectedSourceIndex,
- }));
+ selected: v.version_index === getters.selectedSourceIndex,
+ };
+ });
};
diff --git a/app/assets/javascripts/diffs/store/modules/diff_state.js b/app/assets/javascripts/diffs/store/modules/diff_state.js
index c331e52c887..aa89c74cef0 100644
--- a/app/assets/javascripts/diffs/store/modules/diff_state.js
+++ b/app/assets/javascripts/diffs/store/modules/diff_state.js
@@ -45,4 +45,6 @@ export default () => ({
fileFinderVisible: false,
dismissEndpoint: '',
showSuggestPopover: true,
+ defaultSuggestionCommitMessage: '',
+ mrReviews: {},
});
diff --git a/app/assets/javascripts/diffs/store/mutation_types.js b/app/assets/javascripts/diffs/store/mutation_types.js
index 30097239aaa..4641731c4b6 100644
--- a/app/assets/javascripts/diffs/store/mutation_types.js
+++ b/app/assets/javascripts/diffs/store/mutation_types.js
@@ -7,6 +7,8 @@ export const SET_DIFF_METADATA = 'SET_DIFF_METADATA';
export const SET_DIFF_DATA_BATCH = 'SET_DIFF_DATA_BATCH';
export const SET_DIFF_FILES = 'SET_DIFF_FILES';
+export const SET_MR_FILE_REVIEWS = 'SET_MR_FILE_REVIEWS';
+
export const SET_DIFF_VIEW_TYPE = 'SET_DIFF_VIEW_TYPE';
export const SET_COVERAGE_DATA = 'SET_COVERAGE_DATA';
export const SET_MERGE_REQUEST_DIFFS = 'SET_MERGE_REQUEST_DIFFS';
diff --git a/app/assets/javascripts/diffs/store/mutations.js b/app/assets/javascripts/diffs/store/mutations.js
index 19122c3096f..06f0f2c3dfb 100644
--- a/app/assets/javascripts/diffs/store/mutations.js
+++ b/app/assets/javascripts/diffs/store/mutations.js
@@ -36,7 +36,9 @@ export default {
projectPath,
dismissEndpoint,
showSuggestPopover,
+ defaultSuggestionCommitMessage,
viewDiffsFileByFile,
+ mrReviews,
} = options;
Object.assign(state, {
endpoint,
@@ -46,7 +48,9 @@ export default {
projectPath,
dismissEndpoint,
showSuggestPopover,
+ defaultSuggestionCommitMessage,
viewDiffsFileByFile,
+ mrReviews,
});
},
@@ -103,11 +107,11 @@ export default {
},
[types.TOGGLE_LINE_HAS_FORM](state, { lineCode, fileHash, hasForm }) {
- const diffFile = state.diffFiles.find(f => f.file_hash === fileHash);
+ const diffFile = state.diffFiles.find((f) => f.file_hash === fileHash);
if (!diffFile) return;
- diffFile[INLINE_DIFF_LINES_KEY].find(l => l.line_code === lineCode).hasForm = hasForm;
+ diffFile[INLINE_DIFF_LINES_KEY].find((l) => l.line_code === lineCode).hasForm = hasForm;
},
[types.ADD_CONTEXT_LINES](state, options) {
@@ -123,7 +127,7 @@ export default {
bottom,
isExpandDown,
nextLineNumbers,
- ).map(line => {
+ ).map((line) => {
const lineCode =
line.type === 'match'
? `${fileHash}_${line.meta_data.old_pos}_${line.meta_data.new_pos}_match`
@@ -147,8 +151,8 @@ export default {
[types.ADD_COLLAPSED_DIFFS](state, { file, data }) {
const files = prepareDiffData({ diff: data });
- const [newFileData] = files.filter(f => f.file_hash === file.file_hash);
- const selectedFile = state.diffFiles.find(f => f.file_hash === file.file_hash);
+ const [newFileData] = files.filter((f) => f.file_hash === file.file_hash);
+ const selectedFile = state.diffFiles.find((f) => f.file_hash === file.file_hash);
Object.assign(selectedFile, { ...newFileData });
},
@@ -157,9 +161,9 @@ export default {
const discussionLineCodes = [discussion.line_code, ...(discussion.line_codes || [])];
const fileHash = discussion.diff_file.file_hash;
- const lineCheck = line =>
+ const lineCheck = (line) =>
discussionLineCodes.some(
- discussionLineCode =>
+ (discussionLineCode) =>
line.line_code === discussionLineCode &&
isDiscussionApplicableToLine({
discussion,
@@ -177,26 +181,26 @@ export default {
: [],
});
- const setDiscussionsExpanded = line => {
+ const setDiscussionsExpanded = (line) => {
const isLineNoteTargeted =
line.discussions &&
line.discussions.some(
- disc => disc.notes && disc.notes.find(note => hash === `note_${note.id}`),
+ (disc) => disc.notes && disc.notes.find((note) => hash === `note_${note.id}`),
);
return {
...line,
discussionsExpanded:
line.discussions && line.discussions.length
- ? line.discussions.some(disc => !disc.resolved) || isLineNoteTargeted
+ ? line.discussions.some((disc) => !disc.resolved) || isLineNoteTargeted
: false,
};
};
- state.diffFiles.forEach(file => {
+ state.diffFiles.forEach((file) => {
if (file.file_hash === fileHash) {
if (file[INLINE_DIFF_LINES_KEY].length) {
- file[INLINE_DIFF_LINES_KEY].forEach(line => {
+ file[INLINE_DIFF_LINES_KEY].forEach((line) => {
Object.assign(
line,
setDiscussionsExpanded(lineCheck(line) ? mapDiscussions(line) : line),
@@ -206,7 +210,7 @@ export default {
if (!file[INLINE_DIFF_LINES_KEY].length) {
const newDiscussions = (file.discussions || [])
- .filter(d => d.id !== discussion.id)
+ .filter((d) => d.id !== discussion.id)
.concat(discussion);
Object.assign(file, {
@@ -218,26 +222,26 @@ export default {
},
[types.REMOVE_LINE_DISCUSSIONS_FOR_FILE](state, { fileHash, lineCode }) {
- const selectedFile = state.diffFiles.find(f => f.file_hash === fileHash);
+ const selectedFile = state.diffFiles.find((f) => f.file_hash === fileHash);
if (selectedFile) {
- updateLineInFile(selectedFile, lineCode, line =>
+ updateLineInFile(selectedFile, lineCode, (line) =>
Object.assign(line, {
- discussions: line.discussions.filter(discussion => discussion.notes.length),
+ discussions: line.discussions.filter((discussion) => discussion.notes.length),
}),
);
if (selectedFile.discussions && selectedFile.discussions.length) {
selectedFile.discussions = selectedFile.discussions.filter(
- discussion => discussion.notes.length,
+ (discussion) => discussion.notes.length,
);
}
}
},
[types.TOGGLE_LINE_DISCUSSIONS](state, { fileHash, lineCode, expanded }) {
- const selectedFile = state.diffFiles.find(f => f.file_hash === fileHash);
+ const selectedFile = state.diffFiles.find((f) => f.file_hash === fileHash);
- updateLineInFile(selectedFile, lineCode, line => {
+ updateLineInFile(selectedFile, lineCode, (line) => {
Object.assign(line, { discussionsExpanded: expanded });
});
},
@@ -260,7 +264,7 @@ export default {
[types.UPDATE_DIFF_FILE_COMMENT_FORM](state, formData) {
const { fileHash } = formData;
- state.commentForms = state.commentForms.map(form => {
+ state.commentForms = state.commentForms.map((form) => {
if (form.fileHash === fileHash) {
return {
...formData,
@@ -271,7 +275,7 @@ export default {
});
},
[types.CLOSE_DIFF_FILE_COMMENT_FORM](state, fileHash) {
- state.commentForms = state.commentForms.filter(form => form.fileHash !== fileHash);
+ state.commentForms = state.commentForms.filter((form) => form.fileHash !== fileHash);
},
[types.SET_HIGHLIGHTED_ROW](state, lineCode) {
state.highlightedRow = lineCode;
@@ -311,7 +315,7 @@ export default {
state,
{ filePath, collapsed, trigger = DIFF_FILE_AUTOMATIC_COLLAPSE },
) {
- const file = state.diffFiles.find(f => f.file_path === filePath);
+ const file = state.diffFiles.find((f) => f.file_path === filePath);
if (file && file.viewer) {
if (trigger === DIFF_FILE_MANUAL_COLLAPSE) {
@@ -328,17 +332,17 @@ export default {
}
},
[types.SET_CURRENT_VIEW_DIFF_FILE_LINES](state, { filePath, lines }) {
- const file = state.diffFiles.find(f => f.file_path === filePath);
+ const file = state.diffFiles.find((f) => f.file_path === filePath);
file[INLINE_DIFF_LINES_KEY] = lines;
},
[types.ADD_CURRENT_VIEW_DIFF_FILE_LINES](state, { filePath, line }) {
- const file = state.diffFiles.find(f => f.file_path === filePath);
+ const file = state.diffFiles.find((f) => f.file_path === filePath);
file[INLINE_DIFF_LINES_KEY].push(line);
},
[types.TOGGLE_DIFF_FILE_RENDERING_MORE](state, filePath) {
- const file = state.diffFiles.find(f => f.file_path === filePath);
+ const file = state.diffFiles.find((f) => f.file_path === filePath);
file.renderingLines = !file.renderingLines;
},
@@ -353,4 +357,7 @@ export default {
[types.SET_FILE_BY_FILE](state, fileByFile) {
state.viewDiffsFileByFile = fileByFile;
},
+ [types.SET_MR_FILE_REVIEWS](state, newReviews) {
+ state.mrReviews = newReviews;
+ },
};
diff --git a/app/assets/javascripts/diffs/store/utils.js b/app/assets/javascripts/diffs/store/utils.js
index 1839df12c96..c52da558be2 100644
--- a/app/assets/javascripts/diffs/store/utils.js
+++ b/app/assets/javascripts/diffs/store/utils.js
@@ -15,13 +15,23 @@ import {
INLINE_DIFF_LINES_KEY,
SHOW_WHITESPACE,
NO_SHOW_WHITESPACE,
+ CONFLICT_OUR,
+ CONFLICT_THEIR,
+ CONFLICT_MARKER,
+ CONFLICT_MARKER_OUR,
+ CONFLICT_MARKER_THEIR,
} from '../constants';
import { prepareRawDiffFile } from '../utils/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);
+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);
+export const isConflictMarker = (line) =>
+ [CONFLICT_MARKER_OUR, CONFLICT_MARKER_THEIR].includes(line.type);
+export const isConflictSeperator = (line) => line.type === CONFLICT_MARKER;
+export const isConflictOur = (line) => line.type === CONFLICT_OUR;
+export const isConflictTheir = (line) => line.type === CONFLICT_THEIR;
/**
* Pass in the inline diff lines array which gets converted
@@ -42,12 +52,22 @@ export const isMeta = line => ['match', 'new-nonewline', 'old-nonewline'].includ
export const parallelizeDiffLines = (diffLines, inline) => {
let freeRightIndex = null;
+ let conflictStartIndex = -1;
const lines = [];
+ // `chunk` is used for dragging to select diff lines
+ // we are restricting commenting to only lines that appear between
+ // "expansion rows". Here equal chunks are lines grouped together
+ // inbetween expansion rows.
+ let chunk = 0;
+
for (let i = 0, diffLinesLength = diffLines.length, index = 0; i < diffLinesLength; i += 1) {
const line = diffLines[i];
+ line.chunk = chunk;
+
+ if (isMeta(line)) chunk += 1;
- if (isRemoved(line) || inline) {
+ if (isRemoved(line) || isConflictOur(line) || inline) {
lines.push({
[LINE_POSITION_LEFT]: line,
[LINE_POSITION_RIGHT]: null,
@@ -58,7 +78,7 @@ export const parallelizeDiffLines = (diffLines, inline) => {
freeRightIndex = index;
}
index += 1;
- } else if (isAdded(line)) {
+ } else if (isAdded(line) || isConflictTheir(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.
@@ -77,15 +97,28 @@ export const parallelizeDiffLines = (diffLines, inline) => {
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,
- });
+ } else if (
+ isMeta(line) ||
+ isUnchanged(line) ||
+ isConflictMarker(line) ||
+ (isConflictSeperator(line) && inline)
+ ) {
+ if (conflictStartIndex <= 0) {
+ // line in the right panel is the same as in the left one
+ lines.push({
+ [LINE_POSITION_LEFT]: line,
+ [LINE_POSITION_RIGHT]: !inline && line,
+ });
- freeRightIndex = null;
- index += 1;
+ if (!inline && isConflictMarker(line)) {
+ conflictStartIndex = index;
+ }
+ freeRightIndex = null;
+ index += 1;
+ } else {
+ lines[conflictStartIndex][LINE_POSITION_RIGHT] = line;
+ conflictStartIndex = -1;
+ }
}
}
@@ -93,10 +126,10 @@ export const parallelizeDiffLines = (diffLines, inline) => {
};
export function findDiffFile(files, match, matchKey = 'file_hash') {
- return files.find(file => file[matchKey] === match);
+ return files.find((file) => file[matchKey] === match);
}
-export const getReversePosition = linePosition => {
+export const getReversePosition = (linePosition) => {
if (linePosition === LINE_POSITION_RIGHT) {
return LINE_POSITION_LEFT;
}
@@ -173,7 +206,7 @@ export const findIndexInInlineLines = (lines, lineNumbers) => {
const { oldLineNumber, newLineNumber } = lineNumbers;
return lines.findIndex(
- line => line.old_line === oldLineNumber && line.new_line === newLineNumber,
+ (line) => line.old_line === oldLineNumber && line.new_line === newLineNumber,
);
};
@@ -346,7 +379,7 @@ export function prepareLineForRenamedFile({ line, diffFile, index = 0 }) {
function prepareDiffFileLines(file) {
const inlineLines = file[INLINE_DIFF_LINES_KEY];
- inlineLines.forEach(line => prepareLine(line, file)); // WARNING: In-Place Mutations!
+ inlineLines.forEach((line) => prepareLine(line, file)); // WARNING: In-Place Mutations!
Object.assign(file, {
inlineLinesCount: inlineLines.length,
@@ -400,7 +433,7 @@ export function getDiffPositionByLineCode(diffFiles) {
let lines = [];
lines = diffFiles.reduce((acc, diffFile) => {
- diffFile[INLINE_DIFF_LINES_KEY].forEach(line => {
+ diffFile[INLINE_DIFF_LINES_KEY].forEach((line) => {
acc.push({ file: diffFile, line });
});
@@ -447,21 +480,21 @@ export function isDiscussionApplicableToLine({ discussion, diffPosition, latestD
...(discussion.positions || []),
];
- const removeLineRange = position => {
+ const removeLineRange = (position) => {
const { line_range: pNotUsed, ...positionNoLineRange } = position;
return positionNoLineRange;
};
return discussionPositions
.map(removeLineRange)
- .some(position => isEqual(position, diffPositionCopy));
+ .some((position) => isEqual(position, diffPositionCopy));
}
// eslint-disable-next-line
return latestDiff && discussion.active && line_code === discussion.line_code;
}
-export const getLowestSingleFolder = folder => {
+export const getLowestSingleFolder = (folder) => {
const getFolder = (blob, start = []) =>
blob.tree.reduce(
(acc, file) => {
@@ -493,8 +526,8 @@ export const getLowestSingleFolder = folder => {
};
};
-export const flattenTree = tree => {
- const flatten = blobTree =>
+export const flattenTree = (tree) => {
+ const flatten = (blobTree) =>
blobTree.reduce((acc, file) => {
const blob = file;
let treeToFlatten = blob.tree;
@@ -516,7 +549,7 @@ export const flattenTree = tree => {
return flatten(tree);
};
-export const generateTreeList = files => {
+export const generateTreeList = (files) => {
const { treeEntries, tree } = files.reduce(
(acc, file) => {
const split = file.new_path.split('/');
@@ -566,8 +599,8 @@ export const generateTreeList = files => {
return { treeEntries, tree: flattenTree(tree) };
};
-export const getDiffMode = diffFile => {
- const diffModeKey = Object.keys(diffModes).find(key => diffFile[`${key}_file`]);
+export const getDiffMode = (diffFile) => {
+ const diffModeKey = Object.keys(diffModes).find((key) => diffFile[`${key}_file`]);
return (
diffModes[diffModeKey] ||
(diffFile.viewer &&
@@ -615,11 +648,11 @@ export const convertExpandLines = ({
return lines;
};
-export const idleCallback = cb => requestIdleCallback(cb);
+export const idleCallback = (cb) => requestIdleCallback(cb);
function getLinesFromFileByLineCode(file, lineCode) {
const inlineLines = file[INLINE_DIFF_LINES_KEY];
- const matchesCode = line => line.line_code === lineCode;
+ const matchesCode = (line) => line.line_code === lineCode;
return inlineLines.filter(matchesCode);
}
@@ -628,15 +661,15 @@ export const updateLineInFile = (selectedFile, lineCode, updateFn) => {
getLinesFromFileByLineCode(selectedFile, lineCode).forEach(updateFn);
};
-export const allDiscussionWrappersExpanded = diff => {
+export const allDiscussionWrappersExpanded = (diff) => {
let discussionsExpanded = true;
- const changeExpandedResult = line => {
+ const changeExpandedResult = (line) => {
if (line && line.discussions.length) {
discussionsExpanded = discussionsExpanded && line.discussionsExpanded;
}
};
- diff[INLINE_DIFF_LINES_KEY].forEach(line => {
+ diff[INLINE_DIFF_LINES_KEY].forEach((line) => {
changeExpandedResult(line);
});