Commit de52dd0d authored by Himanshu Kapoor's avatar Himanshu Kapoor Committed by Vitaly Slobodin

Keep the left sidebar views always alive

Otherwise rendering and destroying the sidebar for large repos
becomes very expensive.
parent 974ff5dd
...@@ -7,9 +7,8 @@ import ActivityBar from './activity_bar.vue'; ...@@ -7,9 +7,8 @@ import ActivityBar from './activity_bar.vue';
import RepoCommitSection from './repo_commit_section.vue'; import RepoCommitSection from './repo_commit_section.vue';
import CommitForm from './commit_sidebar/form.vue'; import CommitForm from './commit_sidebar/form.vue';
import IdeReview from './ide_review.vue'; import IdeReview from './ide_review.vue';
import SuccessMessage from './commit_sidebar/success_message.vue';
import IdeProjectHeader from './ide_project_header.vue'; import IdeProjectHeader from './ide_project_header.vue';
import { leftSidebarViews, SIDEBAR_INIT_WIDTH } from '../constants'; import { SIDEBAR_INIT_WIDTH } from '../constants';
export default { export default {
components: { components: {
...@@ -20,18 +19,11 @@ export default { ...@@ -20,18 +19,11 @@ export default {
IdeTree, IdeTree,
CommitForm, CommitForm,
IdeReview, IdeReview,
SuccessMessage,
IdeProjectHeader, IdeProjectHeader,
}, },
computed: { computed: {
...mapState(['loading', 'currentActivityView', 'changedFiles', 'stagedFiles', 'lastCommitMsg']), ...mapState(['loading', 'currentActivityView', 'changedFiles', 'stagedFiles', 'lastCommitMsg']),
...mapGetters(['currentProject', 'someUncommittedChanges']), ...mapGetters(['currentProject', 'someUncommittedChanges']),
showSuccessMessage() {
return (
this.currentActivityView === leftSidebarViews.edit.name &&
(this.lastCommitMsg && !this.someUncommittedChanges)
);
},
}, },
SIDEBAR_INIT_WIDTH, SIDEBAR_INIT_WIDTH,
}; };
...@@ -44,7 +36,7 @@ export default { ...@@ -44,7 +36,7 @@ export default {
class="multi-file-commit-panel flex-column" class="multi-file-commit-panel flex-column"
> >
<template v-if="loading"> <template v-if="loading">
<div class="multi-file-commit-panel-inner"> <div class="multi-file-commit-panel-inner" data-testid="ide-side-bar-inner">
<div v-for="n in 3" :key="n" class="multi-file-loading-container"> <div v-for="n in 3" :key="n" class="multi-file-loading-container">
<gl-skeleton-loading /> <gl-skeleton-loading />
</div> </div>
...@@ -54,9 +46,11 @@ export default { ...@@ -54,9 +46,11 @@ export default {
<ide-project-header :project="currentProject" /> <ide-project-header :project="currentProject" />
<div class="ide-context-body d-flex flex-fill"> <div class="ide-context-body d-flex flex-fill">
<activity-bar /> <activity-bar />
<div class="multi-file-commit-panel-inner"> <div class="multi-file-commit-panel-inner" data-testid="ide-side-bar-inner">
<div class="multi-file-commit-panel-inner-content"> <div class="multi-file-commit-panel-inner-content">
<component :is="currentActivityView" /> <keep-alive>
<component :is="currentActivityView" />
</keep-alive>
</div> </div>
<commit-form /> <commit-form />
</div> </div>
......
...@@ -47,9 +47,9 @@ export const diffViewerErrors = Object.freeze({ ...@@ -47,9 +47,9 @@ export const diffViewerErrors = Object.freeze({
}); });
export const leftSidebarViews = { export const leftSidebarViews = {
edit: { name: 'ide-tree', keepAlive: false }, edit: { name: 'ide-tree' },
review: { name: 'ide-review', keepAlive: false }, review: { name: 'ide-review' },
commit: { name: 'repo-commit-section', keepAlive: false }, commit: { name: 'repo-commit-section' },
}; };
export const rightSidebarViews = { export const rightSidebarViews = {
......
import Vue from 'vue'; import { mount, createLocalVue } from '@vue/test-utils';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; import Vuex from 'vuex';
import { GlSkeletonLoading } from '@gitlab/ui';
import { createStore } from '~/ide/stores'; import { createStore } from '~/ide/stores';
import ideSidebar from '~/ide/components/ide_side_bar.vue'; import IdeSidebar from '~/ide/components/ide_side_bar.vue';
import IdeTree from '~/ide/components/ide_tree.vue';
import RepoCommitSection from '~/ide/components/repo_commit_section.vue';
import { leftSidebarViews } from '~/ide/constants'; import { leftSidebarViews } from '~/ide/constants';
import { projectData } from '../mock_data'; import { projectData } from '../mock_data';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('IdeSidebar', () => { describe('IdeSidebar', () => {
let vm; let wrapper;
let store; let store;
beforeEach(() => { function createComponent() {
store = createStore(); store = createStore();
const Component = Vue.extend(ideSidebar);
store.state.currentProjectId = 'abcproject'; store.state.currentProjectId = 'abcproject';
store.state.projects.abcproject = projectData; store.state.projects.abcproject = projectData;
vm = createComponentWithStore(Component, store).$mount(); return mount(IdeSidebar, {
}); store,
localVue,
});
}
afterEach(() => { afterEach(() => {
vm.$destroy(); wrapper.destroy();
wrapper = null;
}); });
it('renders a sidebar', () => { it('renders a sidebar', () => {
expect(vm.$el.querySelector('.multi-file-commit-panel-inner')).not.toBeNull(); wrapper = createComponent();
expect(wrapper.find('[data-testid="ide-side-bar-inner"]').exists()).toBe(true);
}); });
it('renders loading icon component', done => { it('renders loading components', async () => {
vm.$store.state.loading = true; wrapper = createComponent();
vm.$nextTick(() => { store.state.loading = true;
expect(vm.$el.querySelector('.multi-file-loading-container')).not.toBeNull();
expect(vm.$el.querySelectorAll('.multi-file-loading-container').length).toBe(3);
done(); await wrapper.vm.$nextTick();
});
expect(wrapper.findAll(GlSkeletonLoading)).toHaveLength(3);
}); });
describe('activityBarComponent', () => { describe('activityBarComponent', () => {
it('renders tree component', () => { it('renders tree component', () => {
expect(vm.$el.querySelector('.ide-file-list')).not.toBeNull(); wrapper = createComponent();
expect(wrapper.find(IdeTree).exists()).toBe(true);
}); });
it('renders commit component', done => { it('renders commit component', async () => {
vm.$store.state.currentActivityView = leftSidebarViews.commit.name; wrapper = createComponent();
store.state.currentActivityView = leftSidebarViews.commit.name;
vm.$nextTick(() => { await wrapper.vm.$nextTick();
expect(vm.$el.querySelector('.multi-file-commit-panel-section')).not.toBeNull();
done(); expect(wrapper.find(RepoCommitSection).exists()).toBe(true);
});
}); });
}); });
it('keeps the current activity view components alive', async () => {
wrapper = createComponent();
const ideTreeComponent = wrapper.find(IdeTree).element;
store.state.currentActivityView = leftSidebarViews.commit.name;
await wrapper.vm.$nextTick();
expect(wrapper.find(IdeTree).exists()).toBe(false);
expect(wrapper.find(RepoCommitSection).exists()).toBe(true);
store.state.currentActivityView = leftSidebarViews.edit.name;
await wrapper.vm.$nextTick();
// reference to the elements remains the same, meaning the components were kept alive
expect(wrapper.find(IdeTree).element).toEqual(ideTreeComponent);
});
}); });
...@@ -20,6 +20,7 @@ exports[`WebIDE runs 1`] = ` ...@@ -20,6 +20,7 @@ exports[`WebIDE runs 1`] = `
> >
<div <div
class="multi-file-commit-panel-inner" class="multi-file-commit-panel-inner"
data-testid="ide-side-bar-inner"
> >
<div <div
class="multi-file-loading-container" class="multi-file-loading-container"
......
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