diff options
author | Phil Hughes <me@iamphill.com> | 2019-02-28 17:14:15 +0300 |
---|---|---|
committer | Mark Chao <mchao@gitlab.com> | 2019-03-06 10:51:44 +0300 |
commit | b14de8e1f519b9b874033f783051814129af176c (patch) | |
tree | 05ebee82e8aa39f4d22bef8602107433e006efba /app/assets/javascripts/diffs/store | |
parent | 2609c2a73e8f8efc4fdd5e13c5378ffae7e4f9ef (diff) |
Add option to expand diff to full file
The user can also toggle between the diff changes and
the full file diff.
Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/19054
Diffstat (limited to 'app/assets/javascripts/diffs/store')
-rw-r--r-- | app/assets/javascripts/diffs/store/actions.js | 35 | ||||
-rw-r--r-- | app/assets/javascripts/diffs/store/mutation_types.js | 4 | ||||
-rw-r--r-- | app/assets/javascripts/diffs/store/mutations.js | 52 | ||||
-rw-r--r-- | app/assets/javascripts/diffs/store/utils.js | 40 |
4 files changed, 129 insertions, 2 deletions
diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js index c40775c3259..57ddc923a3e 100644 --- a/app/assets/javascripts/diffs/store/actions.js +++ b/app/assets/javascripts/diffs/store/actions.js @@ -309,5 +309,40 @@ export const cacheTreeListWidth = (_, size) => { localStorage.setItem(TREE_LIST_WIDTH_STORAGE_KEY, size); }; +export const requestFullDiff = ({ commit }, filePath) => commit(types.REQUEST_FULL_DIFF, filePath); +export const receiveFullDiffSucess = ({ commit }, { filePath, data }) => + commit(types.RECEIVE_FULL_DIFF_SUCCESS, { filePath, data }); +export const receiveFullDiffError = ({ commit }, filePath) => { + commit(types.RECEIVE_FULL_DIFF_ERROR, filePath); + createFlash(s__('MergeRequest|Error loading full diff. Please try again.')); +}; + +export const fetchFullDiff = ({ dispatch }, file) => + axios + .get(file.context_lines_path, { + params: { + full: true, + from_merge_request: true, + }, + }) + .then(({ data }) => dispatch('receiveFullDiffSucess', { filePath: file.file_path, data })) + .then(() => scrollToElement(`#${file.file_hash}`)) + .catch(() => dispatch('receiveFullDiffError', file.file_path)); + +export const toggleFullDiff = ({ dispatch, getters, state }, filePath) => { + const file = state.diffFiles.find(f => f.file_path === filePath); + + dispatch('requestFullDiff', filePath); + + if (file.isShowingFullFile) { + dispatch('loadCollapsedDiff', file) + .then(() => dispatch('assignDiscussionsToDiff', getters.getDiffFileDiscussions(file))) + .then(() => scrollToElement(`#${file.file_hash}`)) + .catch(() => dispatch('receiveFullDiffError', filePath)); + } else { + dispatch('fetchFullDiff', file); + } +}; + // prevent babel-plugin-rewire from generating an invalid default during karma tests export default () => {}; diff --git a/app/assets/javascripts/diffs/store/mutation_types.js b/app/assets/javascripts/diffs/store/mutation_types.js index 71ad108ce88..b441b1de451 100644 --- a/app/assets/javascripts/diffs/store/mutation_types.js +++ b/app/assets/javascripts/diffs/store/mutation_types.js @@ -23,3 +23,7 @@ export const SET_TREE_DATA = 'SET_TREE_DATA'; export const SET_RENDER_TREE_LIST = 'SET_RENDER_TREE_LIST'; export const SET_SHOW_WHITESPACE = 'SET_SHOW_WHITESPACE'; export const TOGGLE_FILE_FINDER_VISIBLE = 'TOGGLE_FILE_FINDER_VISIBLE'; + +export const REQUEST_FULL_DIFF = 'REQUEST_FULL_DIFF'; +export const RECEIVE_FULL_DIFF_SUCCESS = 'RECEIVE_FULL_DIFF_SUCCESS'; +export const RECEIVE_FULL_DIFF_ERROR = 'RECEIVE_FULL_DIFF_ERROR'; diff --git a/app/assets/javascripts/diffs/store/mutations.js b/app/assets/javascripts/diffs/store/mutations.js index 5a27388863c..45187d93fef 100644 --- a/app/assets/javascripts/diffs/store/mutations.js +++ b/app/assets/javascripts/diffs/store/mutations.js @@ -6,8 +6,10 @@ import { addContextLines, prepareDiffData, isDiscussionApplicableToLine, + convertExpandLines, } from './utils'; import * as types from './mutation_types'; +import { OLD_LINE_KEY, NEW_LINE_KEY, TYPE_KEY, LEFT_LINE_KEY } from '../constants'; export default { [types.SET_BASE_CONFIG](state, options) { @@ -248,4 +250,54 @@ export default { [types.TOGGLE_FILE_FINDER_VISIBLE](state, visible) { state.fileFinderVisible = visible; }, + [types.REQUEST_FULL_DIFF](state, filePath) { + const file = findDiffFile(state.diffFiles, filePath, 'file_path'); + + file.isLoadingFullFile = true; + }, + [types.RECEIVE_FULL_DIFF_ERROR](state, filePath) { + const file = findDiffFile(state.diffFiles, filePath, 'file_path'); + + file.isLoadingFullFile = false; + }, + [types.RECEIVE_FULL_DIFF_SUCCESS](state, { filePath, data }) { + const file = findDiffFile(state.diffFiles, filePath, 'file_path'); + + file.isShowingFullFile = true; + file.isLoadingFullFile = false; + + file.highlighted_diff_lines = convertExpandLines({ + diffLines: file.highlighted_diff_lines, + typeKey: [TYPE_KEY], + oldLineKey: [OLD_LINE_KEY], + newLineKey: [NEW_LINE_KEY], + data, + mapLine: ({ line, oldLine, newLine }) => ({ + ...line, + old_line: oldLine, + new_line: newLine, + line_code: `${file.file_hash}_${oldLine}_${newLine}`, + }), + }); + + file.parallel_diff_lines = convertExpandLines({ + diffLines: file.parallel_diff_lines, + typeKey: [LEFT_LINE_KEY, TYPE_KEY], + oldLineKey: [LEFT_LINE_KEY, OLD_LINE_KEY], + newLineKey: [LEFT_LINE_KEY, NEW_LINE_KEY], + data, + mapLine: ({ line, oldLine, newLine }) => ({ + left: { + ...line, + old_line: oldLine, + line_code: `${file.file_hash}_${oldLine}_${newLine}`, + }, + right: { + ...line, + new_line: newLine, + line_code: `${file.file_hash}_${newLine}_${oldLine}`, + }, + }), + }); + }, }; diff --git a/app/assets/javascripts/diffs/store/utils.js b/app/assets/javascripts/diffs/store/utils.js index 247d1e65fea..27a79369a24 100644 --- a/app/assets/javascripts/diffs/store/utils.js +++ b/app/assets/javascripts/diffs/store/utils.js @@ -15,8 +15,8 @@ import { TREE_TYPE, } from '../constants'; -export function findDiffFile(files, hash) { - return files.filter(file => file.file_hash === hash)[0]; +export function findDiffFile(files, match, matchKey = 'file_hash') { + return files.find(file => file[matchKey] === match); } export const getReversePosition = linePosition => { @@ -250,6 +250,8 @@ export function prepareDiffData(diffData) { renderIt: showingLines < LINES_TO_BE_RENDERED_DIRECTLY, collapsed: file.viewer.name === diffViewerModes.text && showingLines > MAX_LINES_TO_BE_RENDERED, + isShowingFullFile: false, + isLoadingFullFile: false, discussions: [], }); } @@ -411,3 +413,37 @@ export const getDiffMode = diffFile => { diffModes.replaced ); }; + +export const convertExpandLines = ({ + diffLines, + data, + typeKey, + oldLineKey, + newLineKey, + mapLine, +}) => { + const dataLength = data.length; + + return diffLines.reduce((acc, line, i) => { + if (_.property(typeKey)(line) === 'match') { + const beforeLine = diffLines[i - 1]; + const afterLine = diffLines[i + 1]; + const beforeLineIndex = _.property(newLineKey)(beforeLine) || 0; + const afterLineIndex = _.property(newLineKey)(afterLine) - 1 || dataLength; + + acc.push( + ...data.slice(beforeLineIndex, afterLineIndex).map((l, index) => ({ + ...mapLine({ + line: { ...l, hasForm: false, discussions: [] }, + oldLine: (_.property(oldLineKey)(beforeLine) || 0) + index + 1, + newLine: (_.property(newLineKey)(beforeLine) || 0) + index + 1, + }), + })), + ); + } else { + acc.push(line); + } + + return acc; + }, []); +}; |