Commit 3825c006 authored by Filipa Lacerda's avatar Filipa Lacerda

Merge branch '10898-handle-roadmap-window-resize' into 'master'

Handle window resize event to re-render Roadmap

Closes #10898

See merge request gitlab-org/gitlab-ee!10604
parents 2b38e131 26b647a2
...@@ -42,6 +42,7 @@ export default { ...@@ -42,6 +42,7 @@ export default {
'epics', 'epics',
'timeframe', 'timeframe',
'extendedTimeframe', 'extendedTimeframe',
'windowResizeInProgress',
'epicsFetchInProgress', 'epicsFetchInProgress',
'epicsFetchForTimeframeInProgress', 'epicsFetchForTimeframeInProgress',
'epicsFetchResultEmpty', 'epicsFetchResultEmpty',
...@@ -56,7 +57,12 @@ export default { ...@@ -56,7 +57,12 @@ export default {
return this.timeframe[last]; return this.timeframe[last];
}, },
showRoadmap() { showRoadmap() {
return !this.epicsFetchFailure && !this.epicsFetchInProgress && !this.epicsFetchResultEmpty; return (
!this.windowResizeInProgress &&
!this.epicsFetchFailure &&
!this.epicsFetchInProgress &&
!this.epicsFetchResultEmpty
);
}, },
}, },
watch: { watch: {
...@@ -80,7 +86,13 @@ export default { ...@@ -80,7 +86,13 @@ export default {
window.removeEventListener('resize', this.handleResizeThrottled, false); window.removeEventListener('resize', this.handleResizeThrottled, false);
}, },
methods: { methods: {
...mapActions(['fetchEpics', 'fetchEpicsForTimeframe', 'extendTimeframe', 'refreshEpicDates']), ...mapActions([
'setWindowResizeInProgress',
'fetchEpics',
'fetchEpicsForTimeframe',
'extendTimeframe',
'refreshEpicDates',
]),
/** /**
* Roadmap view works with absolute sizing and positioning * Roadmap view works with absolute sizing and positioning
* of following child components of RoadmapShell; * of following child components of RoadmapShell;
...@@ -92,14 +104,15 @@ export default { ...@@ -92,14 +104,15 @@ export default {
* And hence when window is resized, any size attributes passed * And hence when window is resized, any size attributes passed
* down to child components are no longer valid, so best approach * down to child components are no longer valid, so best approach
* to refresh entire app is to re-render it on resize, hence * to refresh entire app is to re-render it on resize, hence
* we toggle `isLoading` variable which is bound to `RoadmapShell`. * we toggle `windowResizeInProgress` variable which is bound
* to `RoadmapShell`.
*/ */
handleResize() { handleResize() {
this.isLoading = true; this.setWindowResizeInProgress(true);
// We need to debounce the toggle to make sure loading animation // We need to debounce the toggle to make sure loading animation
// shows up while app is being rerendered. // shows up while app is being rerendered.
_.debounce(() => { _.debounce(() => {
this.isLoading = false; this.setWindowResizeInProgress(false);
}, 200)(); }, 200)();
}, },
/** /**
......
...@@ -10,6 +10,9 @@ import * as types from './mutation_types'; ...@@ -10,6 +10,9 @@ import * as types from './mutation_types';
export const setInitialData = ({ commit }, data) => commit(types.SET_INITIAL_DATA, data); export const setInitialData = ({ commit }, data) => commit(types.SET_INITIAL_DATA, data);
export const setWindowResizeInProgress = ({ commit }, inProgress) =>
commit(types.SET_WINDOW_RESIZE_IN_PROGRESS, inProgress);
export const requestEpics = ({ commit }) => commit(types.REQUEST_EPICS); export const requestEpics = ({ commit }) => commit(types.REQUEST_EPICS);
export const requestEpicsForTimeframe = ({ commit }) => commit(types.REQUEST_EPICS_FOR_TIMEFRAME); export const requestEpicsForTimeframe = ({ commit }) => commit(types.REQUEST_EPICS_FOR_TIMEFRAME);
export const receiveEpicsSuccess = ( export const receiveEpicsSuccess = (
......
...@@ -2,6 +2,8 @@ export const SET_INITIAL_DATA = 'SET_INITIAL_DATA'; ...@@ -2,6 +2,8 @@ export const SET_INITIAL_DATA = 'SET_INITIAL_DATA';
export const SET_EPICS = 'SET_EPICS'; export const SET_EPICS = 'SET_EPICS';
export const SET_WINDOW_RESIZE_IN_PROGRESS = 'SET_WINDOW_RESIZE_IN_PROGRESS';
export const UPDATE_EPIC_IDS = 'UPDATE_EPIC_IDS'; export const UPDATE_EPIC_IDS = 'UPDATE_EPIC_IDS';
export const REQUEST_EPICS = 'REQUEST_EPICS'; export const REQUEST_EPICS = 'REQUEST_EPICS';
......
...@@ -9,6 +9,10 @@ export default { ...@@ -9,6 +9,10 @@ export default {
state.epics = epics; state.epics = epics;
}, },
[types.SET_WINDOW_RESIZE_IN_PROGRESS](state, inProgress) {
state.windowResizeInProgress = inProgress;
},
[types.UPDATE_EPIC_IDS](state, epicId) { [types.UPDATE_EPIC_IDS](state, epicId) {
state.epicIds.push(epicId); state.epicIds.push(epicId);
}, },
......
...@@ -17,6 +17,7 @@ export default () => ({ ...@@ -17,6 +17,7 @@ export default () => ({
// UI Flags // UI Flags
defaultInnerHeight: 0, defaultInnerHeight: 0,
isChildEpics: false, isChildEpics: false,
windowResizeInProgress: false,
epicsFetchInProgress: false, epicsFetchInProgress: false,
epicsFetchForTimeframeInProgress: false, epicsFetchForTimeframeInProgress: false,
epicsFetchFailure: false, epicsFetchFailure: false,
......
...@@ -2,6 +2,7 @@ require 'spec_helper' ...@@ -2,6 +2,7 @@ require 'spec_helper'
describe 'group epic roadmap', :js do describe 'group epic roadmap', :js do
include FilteredSearchHelpers include FilteredSearchHelpers
include MobileHelpers
let(:user) { create(:user) } let(:user) { create(:user) }
let(:group) { create(:group) } let(:group) { create(:group) }
...@@ -73,6 +74,18 @@ describe 'group epic roadmap', :js do ...@@ -73,6 +74,18 @@ describe 'group epic roadmap', :js do
expect(page).to have_selector('.epics-list-item .epic-title', count: 3) expect(page).to have_selector('.epics-list-item .epic-title', count: 3)
end end
end end
it 'resizing browser window causes Roadmap to re-render' do
page.within('.group-epics-roadmap .roadmap-container') do
initial_style = find('.roadmap-shell')[:style]
page.current_window.resize_to(2500, 1000)
wait_for_requests
expect(find('.roadmap-shell')[:style]).not_to eq(initial_style)
restore_window_size
end
end
end end
describe 'roadmap page with epics state filter' do describe 'roadmap page with epics state filter' do
......
...@@ -47,7 +47,7 @@ const createComponent = () => { ...@@ -47,7 +47,7 @@ const createComponent = () => {
}); });
}; };
describe('AppComponent', () => { describe('Roadmap AppComponent', () => {
let vm; let vm;
beforeEach(() => { beforeEach(() => {
...@@ -78,7 +78,8 @@ describe('AppComponent', () => { ...@@ -78,7 +78,8 @@ describe('AppComponent', () => {
}); });
describe('showRoadmap', () => { describe('showRoadmap', () => {
it('returns true if `epicsFetchInProgress`, `epicsFetchResultEmpty` and `epicsFetchFailure` are all `false`', () => { it('returns true if `windowResizeInProgress`, `epicsFetchInProgress`, `epicsFetchResultEmpty` and `epicsFetchFailure` are all `false`', () => {
vm.$store.state.windowResizeInProgress = false;
vm.$store.state.epicsFetchInProgress = false; vm.$store.state.epicsFetchInProgress = false;
vm.$store.state.epicsFetchResultEmpty = false; vm.$store.state.epicsFetchResultEmpty = false;
vm.$store.state.epicsFetchFailure = false; vm.$store.state.epicsFetchFailure = false;
...@@ -86,17 +87,29 @@ describe('AppComponent', () => { ...@@ -86,17 +87,29 @@ describe('AppComponent', () => {
expect(vm.showRoadmap).toBe(true); expect(vm.showRoadmap).toBe(true);
}); });
it('returns false if either of `epicsFetchInProgress`, `epicsFetchResultEmpty` and `epicsFetchFailure` is `true`', () => { it('returns false if either of `windowResizeInProgress`, `epicsFetchInProgress`, `epicsFetchResultEmpty` and `epicsFetchFailure` is `true`', () => {
vm.$store.state.windowResizeInProgress = true;
vm.$store.state.epicsFetchInProgress = false;
vm.$store.state.epicsFetchResultEmpty = false;
vm.$store.state.epicsFetchFailure = false;
expect(vm.showRoadmap).toBe(false);
vm.$store.state.windowResizeInProgress = false;
vm.$store.state.epicsFetchInProgress = true; vm.$store.state.epicsFetchInProgress = true;
vm.$store.state.epicsFetchResultEmpty = false; vm.$store.state.epicsFetchResultEmpty = false;
vm.$store.state.epicsFetchFailure = false; vm.$store.state.epicsFetchFailure = false;
expect(vm.showRoadmap).toBe(false); expect(vm.showRoadmap).toBe(false);
vm.$store.state.windowResizeInProgress = false;
vm.$store.state.epicsFetchInProgress = false; vm.$store.state.epicsFetchInProgress = false;
vm.$store.state.epicsFetchResultEmpty = true; vm.$store.state.epicsFetchResultEmpty = true;
vm.$store.state.epicsFetchFailure = false; vm.$store.state.epicsFetchFailure = false;
expect(vm.showRoadmap).toBe(false); expect(vm.showRoadmap).toBe(false);
vm.$store.state.windowResizeInProgress = false;
vm.$store.state.epicsFetchInProgress = false; vm.$store.state.epicsFetchInProgress = false;
vm.$store.state.epicsFetchResultEmpty = false; vm.$store.state.epicsFetchResultEmpty = false;
vm.$store.state.epicsFetchFailure = true; vm.$store.state.epicsFetchFailure = true;
......
...@@ -63,6 +63,19 @@ describe('Roadmap Vuex Actions', () => { ...@@ -63,6 +63,19 @@ describe('Roadmap Vuex Actions', () => {
}); });
}); });
describe('setWindowResizeInProgress', () => {
it('Should set value of `state.windowResizeInProgress` based on provided value', done => {
testAction(
actions.setWindowResizeInProgress,
true,
state,
[{ type: types.SET_WINDOW_RESIZE_IN_PROGRESS, payload: true }],
[],
done,
);
});
});
describe('requestEpics', () => { describe('requestEpics', () => {
it('Should set `epicsFetchInProgress` to true', done => { it('Should set `epicsFetchInProgress` to true', done => {
testAction(actions.requestEpics, {}, state, [{ type: 'REQUEST_EPICS' }], [], done); testAction(actions.requestEpics, {}, state, [{ type: 'REQUEST_EPICS' }], [], done);
......
...@@ -15,6 +15,7 @@ describe('Roadmap Store Mutations', () => { ...@@ -15,6 +15,7 @@ describe('Roadmap Store Mutations', () => {
describe('SET_INITIAL_DATA', () => { describe('SET_INITIAL_DATA', () => {
it('Should set initial Roadmap data to state', () => { it('Should set initial Roadmap data to state', () => {
const initialData = { const initialData = {
windowResizeInProgress: false,
epicsFetchInProgress: false, epicsFetchInProgress: false,
epicsFetchForTimeframeInProgress: false, epicsFetchForTimeframeInProgress: false,
epicsFetchFailure: false, epicsFetchFailure: false,
...@@ -47,6 +48,14 @@ describe('Roadmap Store Mutations', () => { ...@@ -47,6 +48,14 @@ describe('Roadmap Store Mutations', () => {
}); });
}); });
describe('SET_WINDOW_RESIZE_IN_PROGRESS', () => {
it('Should set value of `state.windowResizeInProgress` based on provided value', () => {
mutations[types.SET_WINDOW_RESIZE_IN_PROGRESS](state, true);
expect(state.windowResizeInProgress).toEqual(true);
});
});
describe('UPDATE_EPIC_IDS', () => { describe('UPDATE_EPIC_IDS', () => {
it('Should insert provided epicId to epicIds array in state', () => { it('Should insert provided epicId to epicIds array in state', () => {
mutations[types.UPDATE_EPIC_IDS](state, 22); mutations[types.UPDATE_EPIC_IDS](state, 22);
......
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