Commit 0d1d35ef authored by Denys Mishunov's avatar Denys Mishunov Committed by Kushal Pandya

Switch viewer switcher to v-model

Since there's just one parameter to keep an eye on in
blob_header_viewer_switcher, instead of relying on an eventHub,
transform it into v-model aware component.
parent c7d27481
......@@ -2,8 +2,7 @@
import ViewerSwitcher from './blob_header_viewer_switcher.vue';
import DefaultActions from './blob_header_default_actions.vue';
import BlobFilepath from './blob_header_filepath.vue';
import eventHub from '../event_hub';
import { RICH_BLOB_VIEWER, SIMPLE_BLOB_VIEWER } from './constants';
import { SIMPLE_BLOB_VIEWER } from './constants';
export default {
components: {
......@@ -26,10 +25,15 @@ export default {
required: false,
default: false,
},
activeViewerType: {
type: String,
required: false,
default: SIMPLE_BLOB_VIEWER,
},
},
data() {
return {
activeViewer: this.blob.richViewer ? RICH_BLOB_VIEWER : SIMPLE_BLOB_VIEWER,
viewer: this.hideViewerSwitcher ? null : this.activeViewerType,
};
},
computed: {
......@@ -40,19 +44,16 @@ export default {
return !this.hideDefaultActions;
},
},
created() {
if (this.showViewerSwitcher) {
eventHub.$on('switch-viewer', this.setActiveViewer);
}
},
beforeDestroy() {
if (this.showViewerSwitcher) {
eventHub.$off('switch-viewer', this.setActiveViewer);
}
watch: {
viewer(newVal, oldVal) {
if (!this.hideViewerSwitcher && newVal !== oldVal) {
this.$emit('viewer-changed', newVal);
}
},
},
methods: {
setActiveViewer(viewer) {
this.activeViewer = viewer;
proxyCopyRequest() {
this.$emit('copy');
},
},
};
......@@ -66,11 +67,16 @@ export default {
</blob-filepath>
<div class="file-actions d-none d-sm-block">
<viewer-switcher v-if="showViewerSwitcher" :blob="blob" :active-viewer="activeViewer" />
<viewer-switcher v-if="showViewerSwitcher" v-model="viewer" />
<slot name="actions"></slot>
<default-actions v-if="showDefaultActions" :blob="blob" :active-viewer="activeViewer" />
<default-actions
v-if="showDefaultActions"
:raw-path="blob.rawPath"
:active-viewer="viewer"
@copy="proxyCopyRequest"
/>
</div>
</div>
</template>
......@@ -7,7 +7,6 @@ import {
RICH_BLOB_VIEWER,
SIMPLE_BLOB_VIEWER,
} from './constants';
import eventHub from '../event_hub';
export default {
components: {
......@@ -19,8 +18,8 @@ export default {
GlTooltip: GlTooltipDirective,
},
props: {
blob: {
type: Object,
rawPath: {
type: String,
required: true,
},
activeViewer: {
......@@ -30,11 +29,8 @@ export default {
},
},
computed: {
rawUrl() {
return this.blob.rawPath;
},
downloadUrl() {
return `${this.blob.rawPath}?inline=false`;
return `${this.rawPath}?inline=false`;
},
copyDisabled() {
return this.activeViewer === RICH_BLOB_VIEWER;
......@@ -42,7 +38,7 @@ export default {
},
methods: {
requestCopyContents() {
eventHub.$emit('copy');
this.$emit('copy');
},
},
BTN_COPY_CONTENTS_TITLE,
......@@ -65,7 +61,7 @@ export default {
v-gl-tooltip.hover
:aria-label="$options.BTN_RAW_TITLE"
:title="$options.BTN_RAW_TITLE"
:href="rawUrl"
:href="rawPath"
target="_blank"
>
<gl-icon name="doc-code" :size="14" />
......
......@@ -6,7 +6,6 @@ import {
SIMPLE_BLOB_VIEWER,
SIMPLE_BLOB_VIEWER_TITLE,
} from './constants';
import eventHub from '../event_hub';
export default {
components: {
......@@ -18,11 +17,7 @@ export default {
GlTooltip: GlTooltipDirective,
},
props: {
blob: {
type: Object,
required: true,
},
activeViewer: {
value: {
type: String,
default: SIMPLE_BLOB_VIEWER,
required: false,
......@@ -30,16 +25,16 @@ export default {
},
computed: {
isSimpleViewer() {
return this.activeViewer === SIMPLE_BLOB_VIEWER;
return this.value === SIMPLE_BLOB_VIEWER;
},
isRichViewer() {
return this.activeViewer === RICH_BLOB_VIEWER;
return this.value === RICH_BLOB_VIEWER;
},
},
methods: {
switchToViewer(viewer) {
if (viewer !== this.activeViewer) {
eventHub.$emit('switch-viewer', viewer);
if (viewer !== this.value) {
this.$emit('input', viewer);
}
},
},
......
import Vue from 'vue';
export default new Vue();
......@@ -12,13 +12,12 @@ exports[`Blob Header Default Actions rendering matches the snapshot 1`] = `
class="file-actions d-none d-sm-block"
>
<viewer-switcher-stub
activeviewer="rich"
blob="[object Object]"
value="simple"
/>
<default-actions-stub
activeviewer="rich"
blob="[object Object]"
activeviewer="simple"
rawpath="/flightjs/flight/snippets/51/raw"
/>
</div>
</div>
......
......@@ -8,7 +8,6 @@ import {
} from '~/blob/components/constants';
import { GlButtonGroup, GlButton } from '@gitlab/ui';
import { Blob } from './mock_data';
import eventHub from '~/blob/event_hub';
describe('Blob Header Default Actions', () => {
let wrapper;
......@@ -16,10 +15,10 @@ describe('Blob Header Default Actions', () => {
let buttons;
const hrefPrefix = 'http://localhost';
function createComponent(blobProps = {}, propsData = {}) {
function createComponent(propsData = {}) {
wrapper = mount(BlobHeaderActions, {
propsData: {
blob: Object.assign({}, Blob, blobProps),
rawPath: Blob.rawPath,
...propsData,
},
});
......@@ -60,12 +59,9 @@ describe('Blob Header Default Actions', () => {
});
it('renders "Copy file contents" button as disables if the viewer is Rich', () => {
createComponent(
{},
{
activeViewer: RICH_BLOB_VIEWER,
},
);
createComponent({
activeViewer: RICH_BLOB_VIEWER,
});
buttons = wrapper.findAll(GlButton);
expect(buttons.at(0).attributes('disabled')).toBeTruthy();
......@@ -74,10 +70,10 @@ describe('Blob Header Default Actions', () => {
describe('functionally', () => {
it('emits an event when a Copy Contents button is clicked', () => {
jest.spyOn(eventHub, '$emit');
jest.spyOn(wrapper.vm, '$emit');
buttons.at(0).vm.$emit('click');
expect(eventHub.$emit).toHaveBeenCalledWith('copy');
expect(wrapper.vm.$emit).toHaveBeenCalledWith('copy');
});
});
});
......@@ -3,7 +3,6 @@ import BlobHeader from '~/blob/components/blob_header.vue';
import ViewerSwitcher from '~/blob/components/blob_header_viewer_switcher.vue';
import DefaultActions from '~/blob/components/blob_header_default_actions.vue';
import BlobFilepath from '~/blob/components/blob_header_filepath.vue';
import eventHub from '~/blob/event_hub';
import { Blob } from './mock_data';
......@@ -21,10 +20,6 @@ describe('Blob Header Default Actions', () => {
});
}
beforeEach(() => {
createComponent();
});
afterEach(() => {
wrapper.destroy();
});
......@@ -96,37 +91,48 @@ describe('Blob Header Default Actions', () => {
describe('functionality', () => {
const newViewer = 'Foo Bar';
const activeViewerType = 'Alpha Beta';
it('listens to "switch-view" event when viewer switcher is shown and updates activeViewer', () => {
expect(wrapper.vm.showViewerSwitcher).toBe(true);
eventHub.$emit('switch-viewer', newViewer);
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.activeViewer).toBe(newViewer);
});
});
it('does not update active viewer if the switcher is not shown', () => {
const activeViewer = 'Alpha Beta';
const factory = (hideViewerSwitcher = false) => {
createComponent(
{},
{},
{
data() {
return {
activeViewer,
};
},
},
{
hideViewerSwitcher: true,
activeViewerType,
hideViewerSwitcher,
},
);
};
it('by default sets viewer data based on activeViewerType', () => {
factory();
expect(wrapper.vm.viewer).toBe(activeViewerType);
});
it('sets viewer to null if the viewer switcher should be hidden', () => {
factory(true);
expect(wrapper.vm.viewer).toBe(null);
});
it('watches the changes in viewer data and emits event when the change is registered', () => {
factory();
jest.spyOn(wrapper.vm, '$emit');
wrapper.vm.viewer = newViewer;
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.$emit).toHaveBeenCalledWith('viewer-changed', newViewer);
});
});
it('does not emit event if the switcher is not rendered', () => {
factory(true);
expect(wrapper.vm.showViewerSwitcher).toBe(false);
eventHub.$emit('switch-viewer', newViewer);
jest.spyOn(wrapper.vm, '$emit');
wrapper.vm.viewer = newViewer;
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.activeViewer).toBe(activeViewer);
expect(wrapper.vm.$emit).not.toHaveBeenCalled();
});
});
});
......
......@@ -7,18 +7,13 @@ import {
SIMPLE_BLOB_VIEWER_TITLE,
} from '~/blob/components/constants';
import { GlButtonGroup, GlButton } from '@gitlab/ui';
import { Blob } from './mock_data';
import eventHub from '~/blob/event_hub';
describe('Blob Header Viewer Switcher', () => {
let wrapper;
function createComponent(blobProps = {}, propsData = {}) {
function createComponent(propsData = {}) {
wrapper = mount(BlobHeaderViewerSwitcher, {
propsData: {
blob: Object.assign({}, Blob, blobProps),
...propsData,
},
propsData,
});
}
......@@ -29,7 +24,7 @@ describe('Blob Header Viewer Switcher', () => {
describe('intiialization', () => {
it('is initialized with simple viewer as active', () => {
createComponent();
expect(wrapper.vm.activeViewer).toBe(SIMPLE_BLOB_VIEWER);
expect(wrapper.vm.value).toBe(SIMPLE_BLOB_VIEWER);
});
});
......@@ -60,42 +55,42 @@ describe('Blob Header Viewer Switcher', () => {
let simpleBtn;
let richBtn;
function factory(propsOptions = {}) {
createComponent({}, propsOptions);
function factory(propsData = {}) {
createComponent(propsData);
buttons = wrapper.findAll(GlButton);
simpleBtn = buttons.at(0);
richBtn = buttons.at(1);
jest.spyOn(eventHub, '$emit');
jest.spyOn(wrapper.vm, '$emit');
}
it('does not switch the viewer if the selected one is already active', () => {
factory();
expect(wrapper.vm.activeViewer).toBe(SIMPLE_BLOB_VIEWER);
expect(wrapper.vm.value).toBe(SIMPLE_BLOB_VIEWER);
simpleBtn.vm.$emit('click');
expect(wrapper.vm.activeViewer).toBe(SIMPLE_BLOB_VIEWER);
expect(eventHub.$emit).not.toHaveBeenCalled();
expect(wrapper.vm.value).toBe(SIMPLE_BLOB_VIEWER);
expect(wrapper.vm.$emit).not.toHaveBeenCalled();
});
it('emits an event when a Rich Viewer button is clicked', () => {
factory();
expect(wrapper.vm.activeViewer).toBe(SIMPLE_BLOB_VIEWER);
expect(wrapper.vm.value).toBe(SIMPLE_BLOB_VIEWER);
richBtn.vm.$emit('click');
return wrapper.vm.$nextTick().then(() => {
expect(eventHub.$emit).toHaveBeenCalledWith('switch-viewer', RICH_BLOB_VIEWER);
expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', RICH_BLOB_VIEWER);
});
});
it('emits an event when a Simple Viewer button is clicked', () => {
factory({
activeViewer: RICH_BLOB_VIEWER,
value: RICH_BLOB_VIEWER,
});
simpleBtn.vm.$emit('click');
return wrapper.vm.$nextTick().then(() => {
expect(eventHub.$emit).toHaveBeenCalledWith('switch-viewer', SIMPLE_BLOB_VIEWER);
expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', SIMPLE_BLOB_VIEWER);
});
});
});
......
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