Commit bcb4250b authored by Tim Zallmann's avatar Tim Zallmann

Merge branch 'acet-fix-fetching-diffs-data' into 'master'

Prevent fetching diffs and discussions data unnecessarily on MR page

Closes #48493

See merge request gitlab-org/gitlab-ce!20190
parents 7c6d7acc d690cd99
...@@ -3,6 +3,7 @@ import { mapState, mapGetters, mapActions } from 'vuex'; ...@@ -3,6 +3,7 @@ import { mapState, mapGetters, mapActions } from 'vuex';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import { __ } from '~/locale'; import { __ } from '~/locale';
import createFlash from '~/flash'; import createFlash from '~/flash';
import eventHub from '../../notes/event_hub';
import LoadingIcon from '../../vue_shared/components/loading_icon.vue'; import LoadingIcon from '../../vue_shared/components/loading_icon.vue';
import CompareVersions from './compare_versions.vue'; import CompareVersions from './compare_versions.vue';
import ChangedFiles from './changed_files.vue'; import ChangedFiles from './changed_files.vue';
...@@ -62,7 +63,7 @@ export default { ...@@ -62,7 +63,7 @@ export default {
plainDiffPath: state => state.diffs.plainDiffPath, plainDiffPath: state => state.diffs.plainDiffPath,
emailPatchPath: state => state.diffs.emailPatchPath, emailPatchPath: state => state.diffs.emailPatchPath,
}), }),
...mapGetters(['isParallelView']), ...mapGetters(['isParallelView', 'isNotesFetched']),
targetBranch() { targetBranch() {
return { return {
branchName: this.targetBranchName, branchName: this.targetBranchName,
...@@ -94,20 +95,36 @@ export default { ...@@ -94,20 +95,36 @@ export default {
this.adjustView(); this.adjustView();
}, },
shouldShow() { shouldShow() {
// When the shouldShow property changed to true, the route is rendered for the first time
// and if we have the isLoading as true this means we didn't fetch the data
if (this.isLoading) {
this.fetchData();
}
this.adjustView(); this.adjustView();
}, },
}, },
mounted() { mounted() {
this.setBaseConfig({ endpoint: this.endpoint, projectPath: this.projectPath }); this.setBaseConfig({ endpoint: this.endpoint, projectPath: this.projectPath });
this.fetchDiffFiles().catch(() => {
createFlash(__('Fetching diff files failed. Please reload the page to try again!')); if (this.shouldShow) {
}); this.fetchData();
}
}, },
created() { created() {
this.adjustView(); this.adjustView();
}, },
methods: { methods: {
...mapActions(['setBaseConfig', 'fetchDiffFiles']), ...mapActions(['setBaseConfig', 'fetchDiffFiles']),
fetchData() {
this.fetchDiffFiles().catch(() => {
createFlash(__('Something went wrong on our end. Please try again!'));
});
if (!this.isNotesFetched) {
eventHub.$emit('fetchNotesData');
}
},
setActive(filePath) { setActive(filePath) {
this.activeFile = filePath; this.activeFile = filePath;
}, },
......
...@@ -15,10 +15,6 @@ export const setBaseConfig = ({ commit }, options) => { ...@@ -15,10 +15,6 @@ export const setBaseConfig = ({ commit }, options) => {
commit(types.SET_BASE_CONFIG, { endpoint, projectPath }); commit(types.SET_BASE_CONFIG, { endpoint, projectPath });
}; };
export const setLoadingState = ({ commit }, state) => {
commit(types.SET_LOADING, state);
};
export const fetchDiffFiles = ({ state, commit }) => { export const fetchDiffFiles = ({ state, commit }) => {
commit(types.SET_LOADING, true); commit(types.SET_LOADING, true);
...@@ -88,7 +84,6 @@ export const expandAllFiles = ({ commit }) => { ...@@ -88,7 +84,6 @@ export const expandAllFiles = ({ commit }) => {
export default { export default {
setBaseConfig, setBaseConfig,
setLoadingState,
fetchDiffFiles, fetchDiffFiles,
setInlineDiffViewType, setInlineDiffViewType,
setParallelDiffViewType, setParallelDiffViewType,
......
...@@ -45,17 +45,17 @@ export default function initMrNotes() { ...@@ -45,17 +45,17 @@ export default function initMrNotes() {
this.updateDiscussionTabCounter(); this.updateDiscussionTabCounter();
}, },
}, },
created() {
this.setActiveTab(window.mrTabs.getCurrentAction());
},
mounted() { mounted() {
this.notesCountBadge = $('.issuable-details').find('.notes-tab .badge'); this.notesCountBadge = $('.issuable-details').find('.notes-tab .badge');
this.setActiveTab(window.mrTabs.getCurrentAction());
window.mrTabs.eventHub.$on('MergeRequestTabChange', tab => {
this.setActiveTab(tab);
});
$(document).on('visibilitychange', this.updateDiscussionTabCounter); $(document).on('visibilitychange', this.updateDiscussionTabCounter);
window.mrTabs.eventHub.$on('MergeRequestTabChange', this.setActiveTab);
}, },
beforeDestroy() { beforeDestroy() {
$(document).off('visibilitychange', this.updateDiscussionTabCounter); $(document).off('visibilitychange', this.updateDiscussionTabCounter);
window.mrTabs.eventHub.$off('MergeRequestTabChange', this.setActiveTab);
}, },
methods: { methods: {
...mapActions(['setActiveTab']), ...mapActions(['setActiveTab']),
......
...@@ -3,6 +3,7 @@ import { mapGetters, mapActions } from 'vuex'; ...@@ -3,6 +3,7 @@ import { mapGetters, mapActions } from 'vuex';
import { getLocationHash } from '../../lib/utils/url_utility'; import { getLocationHash } from '../../lib/utils/url_utility';
import Flash from '../../flash'; import Flash from '../../flash';
import * as constants from '../constants'; import * as constants from '../constants';
import eventHub from '../event_hub';
import noteableNote from './noteable_note.vue'; import noteableNote from './noteable_note.vue';
import noteableDiscussion from './noteable_discussion.vue'; import noteableDiscussion from './noteable_discussion.vue';
import systemNote from '../../vue_shared/components/notes/system_note.vue'; import systemNote from '../../vue_shared/components/notes/system_note.vue';
...@@ -49,7 +50,7 @@ export default { ...@@ -49,7 +50,7 @@ export default {
}; };
}, },
computed: { computed: {
...mapGetters(['discussions', 'getNotesDataByProp', 'discussionCount']), ...mapGetters(['isNotesFetched', 'discussions', 'getNotesDataByProp', 'discussionCount']),
noteableType() { noteableType() {
return this.noteableData.noteableType; return this.noteableData.noteableType;
}, },
...@@ -61,19 +62,30 @@ export default { ...@@ -61,19 +62,30 @@ export default {
isSkeletonNote: true, isSkeletonNote: true,
}); });
} }
return this.discussions; return this.discussions;
}, },
}, },
watch: {
shouldShow() {
if (!this.isNotesFetched) {
this.fetchNotes();
}
},
},
created() { created() {
this.setNotesData(this.notesData); this.setNotesData(this.notesData);
this.setNoteableData(this.noteableData); this.setNoteableData(this.noteableData);
this.setUserData(this.userData); this.setUserData(this.userData);
this.setTargetNoteHash(getLocationHash()); this.setTargetNoteHash(getLocationHash());
eventHub.$once('fetchNotesData', this.fetchNotes);
}, },
mounted() { mounted() {
if (this.shouldShow) {
this.fetchNotes(); this.fetchNotes();
const { parentElement } = this.$el; }
const { parentElement } = this.$el;
if (parentElement && parentElement.classList.contains('js-vue-notes-event')) { if (parentElement && parentElement.classList.contains('js-vue-notes-event')) {
parentElement.addEventListener('toggleAward', event => { parentElement.addEventListener('toggleAward', event => {
const { awardName, noteId } = event.detail; const { awardName, noteId } = event.detail;
...@@ -93,6 +105,7 @@ export default { ...@@ -93,6 +105,7 @@ export default {
setLastFetchedAt: 'setLastFetchedAt', setLastFetchedAt: 'setLastFetchedAt',
setTargetNoteHash: 'setTargetNoteHash', setTargetNoteHash: 'setTargetNoteHash',
toggleDiscussion: 'toggleDiscussion', toggleDiscussion: 'toggleDiscussion',
setNotesFetchedState: 'setNotesFetchedState',
}), }),
getComponentName(discussion) { getComponentName(discussion) {
if (discussion.isSkeletonNote) { if (discussion.isSkeletonNote) {
...@@ -119,11 +132,13 @@ export default { ...@@ -119,11 +132,13 @@ export default {
}) })
.then(() => { .then(() => {
this.isLoading = false; this.isLoading = false;
this.setNotesFetchedState(true);
}) })
.then(() => this.$nextTick()) .then(() => this.$nextTick())
.then(() => this.checkLocationHash()) .then(() => this.checkLocationHash())
.catch(() => { .catch(() => {
this.isLoading = false; this.isLoading = false;
this.setNotesFetchedState(true);
Flash('Something went wrong while fetching comments. Please try again.'); Flash('Something went wrong while fetching comments. Please try again.');
}); });
}, },
...@@ -161,11 +176,12 @@ export default { ...@@ -161,11 +176,12 @@ export default {
<template> <template>
<div <div
v-if="shouldShow" v-if="shouldShow"
id="notes"> id="notes"
>
<ul <ul
id="notes-list" id="notes-list"
class="notes main-notes-list timeline"> class="notes main-notes-list timeline"
>
<component <component
v-for="discussion in allDiscussions" v-for="discussion in allDiscussions"
:is="getComponentName(discussion)" :is="getComponentName(discussion)"
......
...@@ -28,6 +28,9 @@ export const setInitialNotes = ({ commit }, discussions) => ...@@ -28,6 +28,9 @@ export const setInitialNotes = ({ commit }, discussions) =>
export const setTargetNoteHash = ({ commit }, data) => commit(types.SET_TARGET_NOTE_HASH, data); export const setTargetNoteHash = ({ commit }, data) => commit(types.SET_TARGET_NOTE_HASH, data);
export const setNotesFetchedState = ({ commit }, state) =>
commit(types.SET_NOTES_FETCHED_STATE, state);
export const toggleDiscussion = ({ commit }, data) => commit(types.TOGGLE_DISCUSSION, data); export const toggleDiscussion = ({ commit }, data) => commit(types.TOGGLE_DISCUSSION, data);
export const fetchDiscussions = ({ commit }, path) => export const fetchDiscussions = ({ commit }, path) =>
......
...@@ -8,6 +8,8 @@ export const targetNoteHash = state => state.targetNoteHash; ...@@ -8,6 +8,8 @@ export const targetNoteHash = state => state.targetNoteHash;
export const getNotesData = state => state.notesData; export const getNotesData = state => state.notesData;
export const isNotesFetched = state => state.isNotesFetched;
export const getNotesDataByProp = state => prop => state.notesData[prop]; export const getNotesDataByProp = state => prop => state.notesData[prop];
export const getNoteableData = state => state.noteableData; export const getNoteableData = state => state.noteableData;
......
...@@ -10,6 +10,7 @@ export default { ...@@ -10,6 +10,7 @@ export default {
// View layer // View layer
isToggleStateButtonLoading: false, isToggleStateButtonLoading: false,
isNotesFetched: false,
// holds endpoints and permissions provided through haml // holds endpoints and permissions provided through haml
notesData: { notesData: {
......
...@@ -15,6 +15,7 @@ export const TOGGLE_DISCUSSION = 'TOGGLE_DISCUSSION'; ...@@ -15,6 +15,7 @@ export const TOGGLE_DISCUSSION = 'TOGGLE_DISCUSSION';
export const UPDATE_NOTE = 'UPDATE_NOTE'; export const UPDATE_NOTE = 'UPDATE_NOTE';
export const UPDATE_DISCUSSION = 'UPDATE_DISCUSSION'; export const UPDATE_DISCUSSION = 'UPDATE_DISCUSSION';
export const SET_DISCUSSION_DIFF_LINES = 'SET_DISCUSSION_DIFF_LINES'; export const SET_DISCUSSION_DIFF_LINES = 'SET_DISCUSSION_DIFF_LINES';
export const SET_NOTES_FETCHED_STATE = 'SET_NOTES_FETCHED_STATE';
// Issue // Issue
export const CLOSE_ISSUE = 'CLOSE_ISSUE'; export const CLOSE_ISSUE = 'CLOSE_ISSUE';
......
...@@ -205,6 +205,10 @@ export default { ...@@ -205,6 +205,10 @@ export default {
Object.assign(state, { isToggleStateButtonLoading: value }); Object.assign(state, { isToggleStateButtonLoading: value });
}, },
[types.SET_NOTES_FETCHED_STATE](state, value) {
Object.assign(state, { isNotesFetched: value });
},
[types.SET_DISCUSSION_DIFF_LINES](state, { discussionId, diffLines }) { [types.SET_DISCUSSION_DIFF_LINES](state, { discussionId, diffLines }) {
const discussion = utils.findNoteObjectById(state.discussions, discussionId); const discussion = utils.findNoteObjectById(state.discussions, discussionId);
const index = state.discussions.indexOf(discussion); const index = state.discussions.indexOf(discussion);
......
...@@ -5,7 +5,6 @@ import { ...@@ -5,7 +5,6 @@ import {
INLINE_DIFF_VIEW_TYPE, INLINE_DIFF_VIEW_TYPE,
PARALLEL_DIFF_VIEW_TYPE, PARALLEL_DIFF_VIEW_TYPE,
} from '~/diffs/constants'; } from '~/diffs/constants';
import store from '~/diffs/store';
import * as actions from '~/diffs/store/actions'; import * as actions from '~/diffs/store/actions';
import * as types from '~/diffs/store/mutation_types'; import * as types from '~/diffs/store/mutation_types';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
...@@ -28,22 +27,6 @@ describe('DiffsStoreActions', () => { ...@@ -28,22 +27,6 @@ describe('DiffsStoreActions', () => {
}); });
}); });
describe('setLoadingState', () => {
it('should set loading state', done => {
expect(store.state.diffs.isLoading).toEqual(true);
const loadingState = false;
testAction(
actions.setLoadingState,
loadingState,
{},
[{ type: types.SET_LOADING, payload: loadingState }],
[],
done,
);
});
});
describe('fetchDiffFiles', () => { describe('fetchDiffFiles', () => {
it('should fetch diff files', done => { it('should fetch diff files', done => {
const endpoint = '/fetch/diff/files'; const endpoint = '/fetch/diff/files';
......
...@@ -291,4 +291,17 @@ describe('Actions Notes Store', () => { ...@@ -291,4 +291,17 @@ describe('Actions Notes Store', () => {
.catch(done.fail); .catch(done.fail);
}); });
}); });
describe('setNotesFetchedState', () => {
it('should set notes fetched state', done => {
testAction(
actions.setNotesFetchedState,
true,
{},
[{ type: 'SET_NOTES_FETCHED_STATE', payload: true }],
[],
done,
);
});
});
}); });
...@@ -15,6 +15,7 @@ describe('Getters Notes Store', () => { ...@@ -15,6 +15,7 @@ describe('Getters Notes Store', () => {
discussions: [individualNote], discussions: [individualNote],
targetNoteHash: 'hash', targetNoteHash: 'hash',
lastFetchedAt: 'timestamp', lastFetchedAt: 'timestamp',
isNotesFetched: false,
notesData: notesDataMock, notesData: notesDataMock,
userData: userDataMock, userData: userDataMock,
...@@ -84,4 +85,10 @@ describe('Getters Notes Store', () => { ...@@ -84,4 +85,10 @@ describe('Getters Notes Store', () => {
expect(getters.openState(state)).toEqual(noteableDataMock.state); expect(getters.openState(state)).toEqual(noteableDataMock.state);
}); });
}); });
describe('isNotesFetched', () => {
it('should return the state for the fetching notes', () => {
expect(getters.isNotesFetched(state)).toBeFalsy();
});
});
}); });
...@@ -318,4 +318,15 @@ describe('Notes Store mutations', () => { ...@@ -318,4 +318,15 @@ describe('Notes Store mutations', () => {
expect(state.isToggleStateButtonLoading).toEqual(false); expect(state.isToggleStateButtonLoading).toEqual(false);
}); });
}); });
describe('SET_NOTES_FETCHING_STATE', () => {
it('should set the given state', () => {
const state = {
isNotesFetched: false,
};
mutations.SET_NOTES_FETCHED_STATE(state, true);
expect(state.isNotesFetched).toEqual(true);
});
});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment