summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/diffs/store/mutations.js
blob: 6a57a0755791c5e8408ba054660085172d780ebb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
import Vue from 'vue';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { sortTree } from '~/ide/stores/utils';
import {
  findDiffFile,
  addLineReferences,
  removeMatchLine,
  addContextLines,
  prepareDiffData,
  isDiscussionApplicableToLine,
  generateTreeList,
} from './utils';
import * as types from './mutation_types';

export default {
  [types.SET_BASE_CONFIG](state, options) {
    const { endpoint, projectPath } = options;
    Object.assign(state, { endpoint, projectPath });
  },

  [types.SET_LOADING](state, isLoading) {
    Object.assign(state, { isLoading });
  },

  [types.SET_DIFF_DATA](state, data) {
    const diffData = convertObjectPropsToCamelCase(data, { deep: true });
    prepareDiffData(diffData);
    const { tree, treeEntries } = generateTreeList(diffData.diffFiles);

    Object.assign(state, {
      ...diffData,
      tree: sortTree(tree),
      treeEntries,
    });
  },

  [types.RENDER_FILE](state, file) {
    Object.assign(file, {
      renderIt: true,
    });
  },

  [types.SET_MERGE_REQUEST_DIFFS](state, mergeRequestDiffs) {
    Object.assign(state, {
      mergeRequestDiffs: convertObjectPropsToCamelCase(mergeRequestDiffs, { deep: true }),
    });
  },

  [types.SET_DIFF_VIEW_TYPE](state, diffViewType) {
    Object.assign(state, { diffViewType });
  },

  [types.ADD_COMMENT_FORM_LINE](state, { lineCode }) {
    Vue.set(state.diffLineCommentForms, lineCode, true);
  },

  [types.REMOVE_COMMENT_FORM_LINE](state, { lineCode }) {
    Vue.delete(state.diffLineCommentForms, lineCode);
  },

  [types.ADD_CONTEXT_LINES](state, options) {
    const { lineNumbers, contextLines, fileHash } = options;
    const { bottom } = options.params;
    const diffFile = findDiffFile(state.diffFiles, fileHash);
    const { highlightedDiffLines, parallelDiffLines } = diffFile;

    removeMatchLine(diffFile, lineNumbers, bottom);
    const lines = addLineReferences(contextLines, lineNumbers, bottom);
    addContextLines({
      inlineLines: highlightedDiffLines,
      parallelLines: parallelDiffLines,
      contextLines: lines,
      bottom,
      lineNumbers,
    });
  },

  [types.ADD_COLLAPSED_DIFFS](state, { file, data }) {
    const normalizedData = convertObjectPropsToCamelCase(data, { deep: true });
    prepareDiffData(normalizedData);
    const [newFileData] = normalizedData.diffFiles.filter(f => f.fileHash === file.fileHash);
    const selectedFile = state.diffFiles.find(f => f.fileHash === file.fileHash);
    Object.assign(selectedFile, { ...newFileData });
  },

  [types.EXPAND_ALL_FILES](state) {
    state.diffFiles = state.diffFiles.map(file => ({
      ...file,
      collapsed: false,
    }));
  },

  [types.SET_LINE_DISCUSSIONS_FOR_FILE](state, { diffFile, discussions, diffPositionByLineCode }) {
    const { latestDiff } = state;

    discussions.forEach(discussion => {
      const discussionLineCode = discussion.line_code;
      const lineCheck = ({ lineCode }) =>
        lineCode === discussionLineCode &&
        isDiscussionApplicableToLine({
          discussion,
          diffPosition: diffPositionByLineCode[lineCode],
          latestDiff,
        });

      if (diffFile.highlightedDiffLines) {
        const line = diffFile.highlightedDiffLines.find(lineCheck);

        if (line) {
          Object.assign(line, {
            discussions: line.discussions.concat(discussion),
          });
        }
      }

      if (diffFile.parallelDiffLines) {
        const { left, right } = diffFile.parallelDiffLines.find(
          parallelLine =>
            (parallelLine.left && lineCheck(parallelLine.left)) ||
            (parallelLine.right && lineCheck(parallelLine.right)),
        );
        const line = left && left.lineCode === discussionLineCode ? left : right;

        if (line) {
          Object.assign(line, {
            discussions: line.discussions.concat(discussion),
          });
        }
      }

      if (!diffFile.parallelDiffLines || !diffFile.highlightedDiffLines) {
        Object.assign(diffFile, {
          discussions: diffFile.discussions.concat(discussion),
        });
      }
    });
  },

  [types.REMOVE_LINE_DISCUSSIONS_FOR_FILE](state, { fileHash, lineCode }) {
    const selectedFile = state.diffFiles.find(f => f.fileHash === fileHash);
    if (selectedFile) {
      const targetLine = selectedFile.parallelDiffLines.find(
        line =>
          (line.left && line.left.lineCode === lineCode) ||
          (line.right && line.right.lineCode === lineCode),
      );
      if (targetLine) {
        const side = targetLine.left && targetLine.left.lineCode === lineCode ? 'left' : 'right';

        Object.assign(targetLine[side], {
          discussions: [],
        });
      }

      if (selectedFile.highlightedDiffLines) {
        const targetInlineLine = selectedFile.highlightedDiffLines.find(
          line => line.lineCode === lineCode,
        );

        if (targetInlineLine) {
          Object.assign(targetInlineLine, {
            discussions: [],
          });
        }
      }
    }
  },
  [types.TOGGLE_FOLDER_OPEN](state, path) {
    state.treeEntries[path].opened = !state.treeEntries[path].opened;
  },
  [types.TOGGLE_SHOW_TREE_LIST](state) {
    state.showTreeList = !state.showTreeList;
  },
  [types.UPDATE_CURRENT_DIFF_FILE_ID](state, fileId) {
    state.currentDiffFileId = fileId;
  },
};