Commit a3b8f271 authored by Vitaly Slobodin's avatar Vitaly Slobodin

Merge branch 'move-router-to-component' into 'master'

Move fullscreen logic from router to component

See merge request gitlab-org/gitlab!40818
parents a59c450c 75ca86e7
...@@ -21,6 +21,7 @@ import { ...@@ -21,6 +21,7 @@ import {
updateImageDiffNoteOptimisticResponse, updateImageDiffNoteOptimisticResponse,
toDiffNoteGid, toDiffNoteGid,
extractDesignNoteId, extractDesignNoteId,
getPageLayoutElement,
} from '../../utils/design_management_utils'; } from '../../utils/design_management_utils';
import { import {
updateStoreAfterAddImageDiffNote, updateStoreAfterAddImageDiffNote,
...@@ -38,7 +39,7 @@ import { ...@@ -38,7 +39,7 @@ import {
} from '../../utils/error_messages'; } from '../../utils/error_messages';
import { trackDesignDetailView } from '../../utils/tracking'; import { trackDesignDetailView } from '../../utils/tracking';
import { DESIGNS_ROUTE_NAME } from '../../router/constants'; import { DESIGNS_ROUTE_NAME } from '../../router/constants';
import { ACTIVE_DISCUSSION_SOURCE_TYPES } from '../../constants'; import { ACTIVE_DISCUSSION_SOURCE_TYPES, DESIGN_DETAIL_LAYOUT_CLASSLIST } from '../../constants';
const DEFAULT_SCALE = 1; const DEFAULT_SCALE = 1;
...@@ -300,6 +301,22 @@ export default { ...@@ -300,6 +301,22 @@ export default {
this.resolvedDiscussionsExpanded = !this.resolvedDiscussionsExpanded; this.resolvedDiscussionsExpanded = !this.resolvedDiscussionsExpanded;
}, },
}, },
beforeRouteEnter(to, from, next) {
const pageEl = getPageLayoutElement();
if (pageEl) {
pageEl.classList.add(...DESIGN_DETAIL_LAYOUT_CLASSLIST);
}
next();
},
beforeRouteLeave(to, from, next) {
const pageEl = getPageLayoutElement();
if (pageEl) {
pageEl.classList.remove(...DESIGN_DETAIL_LAYOUT_CLASSLIST);
}
next();
},
createImageDiffNoteMutation, createImageDiffNoteMutation,
DESIGNS_ROUTE_NAME, DESIGNS_ROUTE_NAME,
}; };
......
import Vue from 'vue'; import Vue from 'vue';
import VueRouter from 'vue-router'; import VueRouter from 'vue-router';
import routes from './routes'; import routes from './routes';
import { DESIGN_ROUTE_NAME } from './constants';
import { getPageLayoutElement } from '~/design_management/utils/design_management_utils';
import { DESIGN_DETAIL_LAYOUT_CLASSLIST } from '../constants';
Vue.use(VueRouter); Vue.use(VueRouter);
...@@ -13,20 +10,6 @@ export default function createRouter(base) { ...@@ -13,20 +10,6 @@ export default function createRouter(base) {
mode: 'history', mode: 'history',
routes, routes,
}); });
const pageEl = getPageLayoutElement();
router.beforeEach(({ name }, _, next) => {
// apply a fullscreen layout style in Design View (a.k.a design detail)
if (pageEl) {
if (name === DESIGN_ROUTE_NAME) {
pageEl.classList.add(...DESIGN_DETAIL_LAYOUT_CLASSLIST);
} else {
pageEl.classList.remove(...DESIGN_DETAIL_LAYOUT_CLASSLIST);
}
}
next();
});
return router; return router;
} }
...@@ -24,7 +24,13 @@ import mockAllVersions from '../../mock_data/all_versions'; ...@@ -24,7 +24,13 @@ import mockAllVersions from '../../mock_data/all_versions';
jest.mock('~/flash'); jest.mock('~/flash');
const focusInput = jest.fn(); const focusInput = jest.fn();
const mutate = jest.fn().mockResolvedValue();
const mockPageLayoutElement = {
classList: {
add: jest.fn(),
remove: jest.fn(),
},
};
const DesignReplyForm = { const DesignReplyForm = {
template: '<div><textarea ref="textarea"></textarea></div>', template: '<div><textarea ref="textarea"></textarea></div>',
methods: { methods: {
...@@ -37,6 +43,32 @@ const mockDesignNoDiscussions = { ...@@ -37,6 +43,32 @@ const mockDesignNoDiscussions = {
nodes: [], nodes: [],
}, },
}; };
const newComment = 'new comment';
const annotationCoordinates = {
x: 10,
y: 10,
width: 100,
height: 100,
};
const createDiscussionMutationVariables = {
mutation: createImageDiffNoteMutation,
update: expect.anything(),
variables: {
input: {
body: newComment,
noteableId: design.id,
position: {
headSha: 'headSha',
baseSha: 'baseSha',
startSha: 'startSha',
paths: {
newPath: 'full-design-path',
},
...annotationCoordinates,
},
},
},
};
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(VueRouter); localVue.use(VueRouter);
...@@ -45,35 +77,6 @@ describe('Design management design index page', () => { ...@@ -45,35 +77,6 @@ describe('Design management design index page', () => {
let wrapper; let wrapper;
let router; let router;
const newComment = 'new comment';
const annotationCoordinates = {
x: 10,
y: 10,
width: 100,
height: 100,
};
const createDiscussionMutationVariables = {
mutation: createImageDiffNoteMutation,
update: expect.anything(),
variables: {
input: {
body: newComment,
noteableId: design.id,
position: {
headSha: 'headSha',
baseSha: 'baseSha',
startSha: 'startSha',
paths: {
newPath: 'full-design-path',
},
...annotationCoordinates,
},
},
},
};
const mutate = jest.fn().mockResolvedValue();
const findDiscussionForm = () => wrapper.find(DesignReplyForm); const findDiscussionForm = () => wrapper.find(DesignReplyForm);
const findSidebar = () => wrapper.find(DesignSidebar); const findSidebar = () => wrapper.find(DesignSidebar);
const findDesignPresentation = () => wrapper.find(DesignPresentation); const findDesignPresentation = () => wrapper.find(DesignPresentation);
...@@ -122,19 +125,44 @@ describe('Design management design index page', () => { ...@@ -122,19 +125,44 @@ describe('Design management design index page', () => {
wrapper.destroy(); wrapper.destroy();
}); });
describe('when navigating', () => { describe('when navigating to component', () => {
it('applies fullscreen layout', () => { it('applies fullscreen layout class', () => {
const mockEl = { jest.spyOn(utils, 'getPageLayoutElement').mockReturnValue(mockPageLayoutElement);
classList: {
add: jest.fn(),
remove: jest.fn(),
},
};
jest.spyOn(utils, 'getPageLayoutElement').mockReturnValue(mockEl);
createComponent({ loading: true }); createComponent({ loading: true });
expect(mockEl.classList.add).toHaveBeenCalledTimes(1); expect(mockPageLayoutElement.classList.add).toHaveBeenCalledTimes(1);
expect(mockEl.classList.add).toHaveBeenCalledWith(...DESIGN_DETAIL_LAYOUT_CLASSLIST); expect(mockPageLayoutElement.classList.add).toHaveBeenCalledWith(
...DESIGN_DETAIL_LAYOUT_CLASSLIST,
);
});
});
describe('when navigating within the component', () => {
it('`scale` prop of DesignPresentation component is 1', async () => {
jest.spyOn(utils, 'getPageLayoutElement').mockReturnValue(mockPageLayoutElement);
createComponent({ loading: false }, { data: { design, scale: 2 } });
await wrapper.vm.$nextTick();
expect(findDesignPresentation().props('scale')).toBe(2);
DesignIndex.beforeRouteUpdate.call(wrapper.vm, {}, {}, jest.fn());
await wrapper.vm.$nextTick();
expect(findDesignPresentation().props('scale')).toBe(1);
});
});
describe('when navigating away from component', () => {
it('removes fullscreen layout class', async () => {
jest.spyOn(utils, 'getPageLayoutElement').mockReturnValue(mockPageLayoutElement);
createComponent({ loading: true });
wrapper.vm.$options.beforeRouteLeave[0].call(wrapper.vm, {}, {}, jest.fn());
expect(mockPageLayoutElement.classList.remove).toHaveBeenCalledTimes(1);
expect(mockPageLayoutElement.classList.remove).toHaveBeenCalledWith(
...DESIGN_DETAIL_LAYOUT_CLASSLIST,
);
}); });
}); });
......
...@@ -19,7 +19,6 @@ import { ...@@ -19,7 +19,6 @@ import {
import { deprecatedCreateFlash as createFlash } from '~/flash'; import { deprecatedCreateFlash as createFlash } from '~/flash';
import createRouter from '~/design_management/router'; import createRouter from '~/design_management/router';
import * as utils from '~/design_management/utils/design_management_utils'; import * as utils from '~/design_management/utils/design_management_utils';
import { DESIGN_DETAIL_LAYOUT_CLASSLIST } from '~/design_management/constants';
import { import {
designListQueryResponse, designListQueryResponse,
designUploadMutationCreatedResponse, designUploadMutationCreatedResponse,
...@@ -682,13 +681,6 @@ describe('Design management index page', () => { ...@@ -682,13 +681,6 @@ describe('Design management index page', () => {
}); });
describe('when navigating', () => { describe('when navigating', () => {
it('ensures fullscreen layout is not applied', () => {
createComponent({ loading: true });
expect(mockPageEl.classList.remove).toHaveBeenCalledTimes(1);
expect(mockPageEl.classList.remove).toHaveBeenCalledWith(...DESIGN_DETAIL_LAYOUT_CLASSLIST);
});
it('should trigger a scrollIntoView method if designs route is detected', () => { it('should trigger a scrollIntoView method if designs route is detected', () => {
router.replace({ router.replace({
path: '/designs', path: '/designs',
......
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