Commit d2bd2353 authored by Frederic Caplette's avatar Frederic Caplette

Remember pipeline drawer expanded state in local storage

The drawer default is now open in the pipeline editor section
and if someone collapses it, it will be loaded collapsed
the next time someone comes to the section. The reverse
is also true.
parent 2393b1eb
<script> <script>
import { GlButton, GlIcon } from '@gitlab/ui'; import { GlButton, GlIcon } from '@gitlab/ui';
import { __ } from '~/locale'; import { __ } from '~/locale';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
import { DRAWER_EXPANDED_KEY } from '../../constants';
import FirstPipelineCard from './cards/first_pipeline_card.vue'; import FirstPipelineCard from './cards/first_pipeline_card.vue';
import GettingStartedCard from './cards/getting_started_card.vue'; import GettingStartedCard from './cards/getting_started_card.vue';
import PipelineConfigReferenceCard from './cards/pipeline_config_reference_card.vue'; import PipelineConfigReferenceCard from './cards/pipeline_config_reference_card.vue';
...@@ -14,17 +16,19 @@ export default { ...@@ -14,17 +16,19 @@ export default {
i18n: { i18n: {
toggleTxt: __('Collapse'), toggleTxt: __('Collapse'),
}, },
localDrawerKey: DRAWER_EXPANDED_KEY,
components: { components: {
FirstPipelineCard, FirstPipelineCard,
GettingStartedCard, GettingStartedCard,
PipelineConfigReferenceCard,
VisualizeAndLintCard,
GlButton, GlButton,
GlIcon, GlIcon,
LocalStorageSync,
PipelineConfigReferenceCard,
VisualizeAndLintCard,
}, },
data() { data() {
return { return {
isExpanded: false, isExpanded: true,
topPosition: 0, topPosition: 0,
}; };
}, },
...@@ -61,29 +65,31 @@ export default { ...@@ -61,29 +65,31 @@ export default {
}; };
</script> </script>
<template> <template>
<aside <local-storage-sync v-model="isExpanded" :storage-key="$options.localDrawerKey" as-json>
aria-live="polite" <aside
class="gl-fixed gl-right-0 gl-bg-gray-10 gl-shadow-drawer gl-transition-medium gl-border-l-solid gl-border-1 gl-border-gray-100 gl-h-full gl-z-index-9999 gl-overflow-y-auto" aria-live="polite"
:style="rootStyle" class="gl-fixed gl-right-0 gl-bg-gray-10 gl-shadow-drawer gl-transition-medium gl-border-l-solid gl-border-1 gl-border-gray-100 gl-h-full gl-z-index-9999 gl-overflow-y-auto"
> :style="rootStyle"
<gl-button
category="tertiary"
class="gl-w-full gl-h-9 gl-rounded-0! gl-border-none! gl-border-b-solid! gl-border-1! gl-border-gray-100 gl-text-decoration-none! gl-outline-0! gl-display-flex"
:class="buttonClass"
:title="__('Toggle sidebar')"
@click="toggleDrawer"
> >
<span v-if="isExpanded" class="gl-text-gray-500 gl-mr-3" data-testid="collapse-text"> <gl-button
{{ __('Collapse') }} category="tertiary"
</span> class="gl-w-full gl-h-9 gl-rounded-0! gl-border-none! gl-border-b-solid! gl-border-1! gl-border-gray-100 gl-text-decoration-none! gl-outline-0! gl-display-flex"
<gl-icon data-testid="toggle-icon" :name="buttonIconName" /> :class="buttonClass"
</gl-button> :title="__('Toggle sidebar')"
<div v-if="isExpanded" class="gl-h-full gl-p-5" data-testid="drawer-content"> @click="toggleDrawer"
<getting-started-card class="gl-mb-4" /> >
<first-pipeline-card class="gl-mb-4" /> <span v-if="isExpanded" class="gl-text-gray-500 gl-mr-3" data-testid="collapse-text">
<visualize-and-lint-card class="gl-mb-4" /> {{ __('Collapse') }}
<pipeline-config-reference-card /> </span>
<div class="gl-h-13"></div> <gl-icon data-testid="toggle-icon" :name="buttonIconName" />
</div> </gl-button>
</aside> <div v-if="isExpanded" class="gl-h-full gl-p-5" data-testid="drawer-content">
<getting-started-card class="gl-mb-4" />
<first-pipeline-card class="gl-mb-4" />
<visualize-and-lint-card class="gl-mb-4" />
<pipeline-config-reference-card />
<div class="gl-h-13"></div>
</div>
</aside>
</local-storage-sync>
</template> </template>
...@@ -26,3 +26,5 @@ export const TABS_WITH_COMMIT_FORM = [CREATE_TAB, LINT_TAB, VISUALIZE_TAB]; ...@@ -26,3 +26,5 @@ export const TABS_WITH_COMMIT_FORM = [CREATE_TAB, LINT_TAB, VISUALIZE_TAB];
export const COMMIT_ACTION_CREATE = 'CREATE'; export const COMMIT_ACTION_CREATE = 'CREATE';
export const COMMIT_ACTION_UPDATE = 'UPDATE'; export const COMMIT_ACTION_UPDATE = 'UPDATE';
export const DRAWER_EXPANDED_KEY = 'pipeline_editor_drawer_expanded';
import { GlButton } from '@gitlab/ui'; import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import FirstPipelineCard from '~/pipeline_editor/components/drawer/cards/first_pipeline_card.vue'; import FirstPipelineCard from '~/pipeline_editor/components/drawer/cards/first_pipeline_card.vue';
import GettingStartedCard from '~/pipeline_editor/components/drawer/cards/getting_started_card.vue'; import GettingStartedCard from '~/pipeline_editor/components/drawer/cards/getting_started_card.vue';
import PipelineConfigReferenceCard from '~/pipeline_editor/components/drawer/cards/pipeline_config_reference_card.vue'; import PipelineConfigReferenceCard from '~/pipeline_editor/components/drawer/cards/pipeline_config_reference_card.vue';
import VisualizeAndLintCard from '~/pipeline_editor/components/drawer/cards/visualize_and_lint_card.vue'; import VisualizeAndLintCard from '~/pipeline_editor/components/drawer/cards/visualize_and_lint_card.vue';
import PipelineEditorDrawer from '~/pipeline_editor/components/drawer/pipeline_editor_drawer.vue'; import PipelineEditorDrawer from '~/pipeline_editor/components/drawer/pipeline_editor_drawer.vue';
import { DRAWER_EXPANDED_KEY } from '~/pipeline_editor/constants';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
describe('Pipeline editor drawer', () => { describe('Pipeline editor drawer', () => {
useLocalStorageSpy();
let wrapper; let wrapper;
const createComponent = () => { const createComponent = () => {
wrapper = shallowMount(PipelineEditorDrawer); wrapper = shallowMount(PipelineEditorDrawer, {
stubs: { LocalStorageSync },
});
}; };
const findFirstPipelineCard = () => wrapper.findComponent(FirstPipelineCard); const findFirstPipelineCard = () => wrapper.findComponent(FirstPipelineCard);
...@@ -27,11 +35,13 @@ describe('Pipeline editor drawer', () => { ...@@ -27,11 +35,13 @@ describe('Pipeline editor drawer', () => {
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
localStorage.clear();
}); });
describe('when the drawer is collapsed', () => { describe('when the drawer is collapsed', () => {
beforeEach(() => { beforeEach(async () => {
createComponent(); createComponent();
await clickToggleBtn();
}); });
it('shows the left facing arrow icon', () => { it('shows the left facing arrow icon', () => {
...@@ -58,7 +68,6 @@ describe('Pipeline editor drawer', () => { ...@@ -58,7 +68,6 @@ describe('Pipeline editor drawer', () => {
describe('when the drawer is expanded', () => { describe('when the drawer is expanded', () => {
beforeEach(async () => { beforeEach(async () => {
createComponent(); createComponent();
await clickToggleBtn();
}); });
it('shows the right facing arrow icon', () => { it('shows the right facing arrow icon', () => {
...@@ -88,4 +97,31 @@ describe('Pipeline editor drawer', () => { ...@@ -88,4 +97,31 @@ describe('Pipeline editor drawer', () => {
expect(findDrawerContent().exists()).toBe(false); expect(findDrawerContent().exists()).toBe(false);
}); });
}); });
describe('local storage', () => {
it('saves the drawer expanded value to local storage', async () => {
createComponent();
await clickToggleBtn();
expect(localStorage.setItem.mock.calls).toEqual([[DRAWER_EXPANDED_KEY, 'false']]);
});
it('loads the drawer collapsed when local storage is set to `false`, ', async () => {
localStorage.setItem(DRAWER_EXPANDED_KEY, false);
createComponent();
await nextTick();
expect(findDrawerContent().exists()).toBe(false);
});
it('loads the drawer expanded when local storage is set to `true`, ', async () => {
localStorage.setItem(DRAWER_EXPANDED_KEY, true);
createComponent();
await nextTick();
expect(findDrawerContent().exists()).toBe(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