summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFatih Acet <acetfatih@gmail.com>2018-03-19 15:44:20 +0300
committerFatih Acet <acetfatih@gmail.com>2018-03-19 15:44:20 +0300
commit595d2d811a1cfe5944771da12519cb0a69163bcf (patch)
treeacb7d24ac214caa0d090d7dacb1c4bab73b6dbeb
parente1739e47c5664c93c66dd58ded59f9d79cd8a426 (diff)
downloadgitlab-ce-_mr-refactor-part-10.tar.gz
MR Diffs Refactor Part 10: Diffs app store._mr-refactor-part-10
-rw-r--r--app/assets/javascripts/diffs/store/actions.js49
-rw-r--r--app/assets/javascripts/diffs/store/getters.js10
-rw-r--r--app/assets/javascripts/diffs/store/index.js17
-rw-r--r--app/assets/javascripts/diffs/store/mutation_types.js6
-rw-r--r--app/assets/javascripts/diffs/store/mutations.js112
-rw-r--r--app/assets/javascripts/diffs/store/utils.js83
6 files changed, 277 insertions, 0 deletions
diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js
new file mode 100644
index 00000000000..321967a5479
--- /dev/null
+++ b/app/assets/javascripts/diffs/store/actions.js
@@ -0,0 +1,49 @@
+import Vue from 'vue';
+import VueResource from 'vue-resource';
+import Cookies from 'js-cookie';
+import { handleLocationHash } from '~/lib/utils/common_utils';
+import * as types from './mutation_types';
+import {
+ PARALLEL_DIFF_VIEW_TYPE,
+ INLINE_DIFF_VIEW_TYPE,
+ DIFF_VIEW_COOKIE_NAME,
+} from '../constants';
+
+Vue.use(VueResource);
+
+export const setEndpoint = ({ commit }, endpoint) => {
+ commit(types.SET_ENDPOINT, endpoint);
+};
+
+export const setLoadingState = ({ commit }, state) => {
+ commit(types.SET_LOADING, state);
+};
+
+export const fetchDiffFiles = ({ state, commit }) => {
+ commit(types.SET_LOADING, true);
+
+ return Vue.http
+ .get(state.endpoint)
+ .then(res => res.json())
+ .then(res => {
+ commit(types.SET_LOADING, false);
+ commit(types.SET_DIFF_FILES, res.diff_files);
+ return Vue.nextTick();
+ })
+ .then(handleLocationHash);
+};
+
+export const setDiffViewType = ({ commit }, isParallel) => {
+ const type = isParallel ? PARALLEL_DIFF_VIEW_TYPE : INLINE_DIFF_VIEW_TYPE;
+
+ commit(types.SET_DIFF_VIEW_TYPE, type);
+ Cookies.set(DIFF_VIEW_COOKIE_NAME, type);
+};
+
+export const showCommentForm = ({ commit }, params) => {
+ commit(types.ADD_COMMENT_FORM_LINE, params);
+};
+
+export const cancelCommentForm = ({ commit }, params) => {
+ commit(types.REMOVE_COMMENT_FORM_LINE, params);
+};
diff --git a/app/assets/javascripts/diffs/store/getters.js b/app/assets/javascripts/diffs/store/getters.js
new file mode 100644
index 00000000000..ec4ea070209
--- /dev/null
+++ b/app/assets/javascripts/diffs/store/getters.js
@@ -0,0 +1,10 @@
+import { PARALLEL_DIFF_VIEW_TYPE, INLINE_DIFF_VIEW_TYPE } from '../constants';
+
+export default {
+ isParallelView(state) {
+ return state.diffViewType === PARALLEL_DIFF_VIEW_TYPE;
+ },
+ isInlineView(state) {
+ return state.diffViewType === INLINE_DIFF_VIEW_TYPE;
+ },
+};
diff --git a/app/assets/javascripts/diffs/store/index.js b/app/assets/javascripts/diffs/store/index.js
new file mode 100644
index 00000000000..a25851e2f79
--- /dev/null
+++ b/app/assets/javascripts/diffs/store/index.js
@@ -0,0 +1,17 @@
+import Cookies from 'js-cookie';
+import * as actions from './actions';
+import getters from './getters';
+import mutations from './mutations';
+import { INLINE_DIFF_VIEW_TYPE, DIFF_VIEW_COOKIE_NAME } from '../constants';
+
+export default {
+ state: {
+ isLoading: true,
+ endpoint: '',
+ diffFiles: [],
+ diffViewType: Cookies.get(DIFF_VIEW_COOKIE_NAME) || INLINE_DIFF_VIEW_TYPE,
+ },
+ getters,
+ actions,
+ mutations,
+};
diff --git a/app/assets/javascripts/diffs/store/mutation_types.js b/app/assets/javascripts/diffs/store/mutation_types.js
new file mode 100644
index 00000000000..cec771fc04e
--- /dev/null
+++ b/app/assets/javascripts/diffs/store/mutation_types.js
@@ -0,0 +1,6 @@
+export const SET_ENDPOINT = 'SET_ENDPOINT';
+export const SET_LOADING = 'SET_LOADING';
+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';
diff --git a/app/assets/javascripts/diffs/store/mutations.js b/app/assets/javascripts/diffs/store/mutations.js
new file mode 100644
index 00000000000..d83a966fed9
--- /dev/null
+++ b/app/assets/javascripts/diffs/store/mutations.js
@@ -0,0 +1,112 @@
+import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
+import * as utils from './utils';
+import * as types from './mutation_types';
+import * as constants from '../constants';
+
+export default {
+ [types.SET_ENDPOINT](state, endpoint) {
+ Object.assign(state, { endpoint });
+ },
+
+ [types.SET_LOADING](state, loadingState) {
+ Object.assign(state, { isLoading: loadingState });
+ },
+
+ [types.SET_DIFF_FILES](state, diffFiles) {
+ Object.assign(state, {
+ diffFiles: convertObjectPropsToCamelCase(diffFiles, {
+ deep: true,
+ }),
+ });
+ },
+
+ [types.SET_DIFF_VIEW_TYPE](state, type) {
+ Object.assign(state, { diffViewType: type });
+ },
+
+ [types.ADD_COMMENT_FORM_LINE](state, { diffLines, lineCode, linePosition }) {
+ const index = utils.findDiffLineIndex({
+ diffLines,
+ lineCode,
+ linePosition,
+ });
+ const commentFormType = constants.COMMENT_FORM_TYPE;
+
+ if (!diffLines[index]) {
+ return;
+ }
+
+ const item = linePosition
+ ? diffLines[index][linePosition]
+ : diffLines[index];
+
+ if (!item) {
+ return;
+ }
+
+ // We add forms as another diff line so they have to have a unique id
+ // We later use this id to remove the form from diff lines
+ const id = `${item.lineCode}_CommentForm_${linePosition || ''}`;
+ const targetIndex = index + 1;
+ const targetLine = diffLines[targetIndex];
+ const atTargetIndex = linePosition ? targetLine[linePosition] : targetLine;
+
+ // We already have comment form for target line
+ if (atTargetIndex && atTargetIndex.id === id) {
+ return;
+ }
+
+ // Unique comment form object as a diff line
+ const formObj = {
+ id,
+ type: commentFormType,
+ };
+
+ if (linePosition) {
+ // linePosition is only valid for Parallel mode
+ // Create the final lineObj which will represent the forms as a line
+ // Restore old form in opposite position so we can rerender it
+ const reversePosition = utils.getReversePosition(linePosition);
+ const reverseObj = targetLine[reversePosition];
+ const lineObj = {
+ [linePosition]: formObj,
+ [reversePosition]:
+ reverseObj.type === commentFormType ? reverseObj : {},
+ };
+
+ // Check if there is any comment form on the target position
+ // If we have, we should to remove it because above lineObj should be final version
+ const { left, right } = targetLine;
+ const hasAlreadyForm =
+ left.type === commentFormType || right.type === commentFormType;
+ const spliceCount = hasAlreadyForm ? 1 : 0;
+
+ diffLines.splice(targetIndex, spliceCount, lineObj);
+ } else {
+ diffLines.splice(targetIndex, 0, formObj);
+ }
+ },
+
+ [types.REMOVE_COMMENT_FORM_LINE](state, { diffLines, formId, linePosition }) {
+ const index = utils.findDiffLineIndex({ diffLines, formId, linePosition });
+
+ if (index > -1) {
+ if (linePosition) {
+ const reversePosition = utils.getReversePosition(linePosition);
+ const line = diffLines[index];
+ const reverse = line[reversePosition];
+ const shouldRemove = reverse.type !== constants.COMMENT_FORM_TYPE;
+
+ if (shouldRemove) {
+ diffLines.splice(index, 1);
+ } else {
+ Object.assign(line, {
+ [linePosition]: {},
+ });
+ }
+ } else {
+ diffLines.splice(index, 1);
+ }
+ }
+ },
+};
diff --git a/app/assets/javascripts/diffs/store/utils.js b/app/assets/javascripts/diffs/store/utils.js
new file mode 100644
index 00000000000..9aa44cd4fdb
--- /dev/null
+++ b/app/assets/javascripts/diffs/store/utils.js
@@ -0,0 +1,83 @@
+import _ from 'underscore';
+import {
+ LINE_POSITION_LEFT,
+ LINE_POSITION_RIGHT,
+ TEXT_DIFF_POSITION_TYPE,
+ DIFF_NOTE_TYPE,
+ NEW_LINE_TYPE,
+ OLD_LINE_TYPE,
+} from '../constants';
+
+export const findDiffLineIndex = options => {
+ const { diffLines, lineCode, linePosition, formId } = options;
+
+ return _.findIndex(diffLines, l => {
+ const line = linePosition ? l[linePosition] : l;
+
+ if (!line) {
+ return null;
+ }
+
+ if (formId) {
+ return line.id === formId;
+ }
+
+ return line.lineCode === lineCode;
+ });
+};
+
+export const getReversePosition = linePosition => {
+ if (linePosition === LINE_POSITION_RIGHT) {
+ return LINE_POSITION_LEFT;
+ }
+
+ return LINE_POSITION_RIGHT;
+};
+
+export const getNoteFormData = params => {
+ const {
+ note,
+ noteableType,
+ noteableData,
+ diffFile,
+ noteTargetLine,
+ diffViewType,
+ linePosition,
+ } = params;
+
+ // TODO: Discuss with @felipe_arthur to remove this JSON.stringify
+ const position = JSON.stringify({
+ base_sha: diffFile.diffRefs.baseSha,
+ start_sha: diffFile.diffRefs.startSha,
+ head_sha: diffFile.diffRefs.headSha,
+ old_path: diffFile.oldPath,
+ new_path: diffFile.newPath,
+ position_type: TEXT_DIFF_POSITION_TYPE,
+ old_line: noteTargetLine.oldLine,
+ new_line: noteTargetLine.newLine,
+ });
+
+ // TODO: @fatihacet - Double check empty strings
+ const postData = {
+ view: diffViewType,
+ line_type:
+ linePosition === LINE_POSITION_RIGHT ? NEW_LINE_TYPE : OLD_LINE_TYPE,
+ merge_request_diff_head_sha: diffFile.diffRefs.headSha,
+ in_reply_to_discussion_id: '',
+ note_project_id: '',
+ target_type: noteableType,
+ target_id: noteableData.id,
+ 'note[noteable_type]': noteableType,
+ 'note[noteable_id]': noteableData.id,
+ 'note[commit_id]': '',
+ 'note[type]': DIFF_NOTE_TYPE,
+ 'note[line_code]': noteTargetLine.lineCode,
+ 'note[note]': note,
+ 'note[position]': position,
+ };
+
+ return {
+ endpoint: noteableData.create_note_path,
+ data: postData,
+ };
+};