Commit 26150257 authored by Kushal Pandya's avatar Kushal Pandya

Roadmap TimelineSection Component

parent f7b6f7f3
<script>
import eventHub from '../event_hub';
import { SCROLL_BAR_SIZE } from '../constants';
import timelineHeaderItem from './timeline_header_item.vue';
export default {
components: {
timelineHeaderItem,
},
props: {
epics: {
type: Array,
required: true,
},
timeframe: {
type: Array,
required: true,
},
shellWidth: {
type: Number,
required: true,
},
},
data() {
return {
scrolledHeaderClass: '',
};
},
computed: {
calcShellWidth() {
return this.shellWidth - SCROLL_BAR_SIZE;
},
theadStyles() {
return `width: ${this.calcShellWidth}px;`;
},
},
mounted() {
eventHub.$on('epicsListScrolled', this.handleEpicsListScroll);
},
beforeDestroy() {
eventHub.$off('epicsListScrolled', this.handleEpicsListScroll);
},
methods: {
handleEpicsListScroll(scrollTop) {
// Add class only when content are scrolled at half the height of header
this.scrolledHeaderClass = (scrollTop > this.$el.clientHeight / 2) ? 'scrolled-ahead' : '';
},
},
};
</script>
<template>
<thead
class="roadmap-timeline-section"
:class="scrolledHeaderClass"
:style="theadStyles"
>
<tr>
<th class="timeline-header-blank"></th>
<timeline-header-item
v-for="(timeframeItem, index) in timeframe"
:key="index"
:timeframe-index="index"
:timeframe-item="timeframeItem"
:timeframe="timeframe"
:shell-width="calcShellWidth"
/>
</tr>
</thead>
</template>
import Vue from 'vue';
import roadmapTimelineSectionComponent from 'ee/roadmap/components/roadmap_timeline_section.vue';
import eventHub from 'ee/roadmap/event_hub';
import { mockEpic, mockTimeframe, mockShellWidth } from '../mock_data';
import mountComponent from '../../helpers/vue_mount_component_helper';
const createComponent = ({
epics = [mockEpic],
timeframe = mockTimeframe,
shellWidth = mockShellWidth,
}) => {
const Component = Vue.extend(roadmapTimelineSectionComponent);
return mountComponent(Component, {
epics,
timeframe,
shellWidth,
});
};
describe('RoadmapTimelineSectionComponent', () => {
let vm;
beforeEach(() => {
vm = createComponent({});
});
afterEach(() => {
vm.$destroy();
});
describe('data', () => {
it('returns default data props', () => {
expect(vm.scrolledHeaderClass).toBe('');
});
});
describe('computed', () => {
describe('calcShellWidth', () => {
it('returns shellWidth by deducting Scrollbar size', () => {
// shellWidth is 2000 (as defined above in mockShellWidth)
// SCROLLBAR_SIZE is 15 (as defined in app's constants.js)
// Hence, calcShellWidth = shellWidth - SCROLLBAR_SIZE
expect(vm.calcShellWidth).toBe(1985);
});
});
describe('theadStyles', () => {
it('returns style string for thead based on calcShellWidth', () => {
expect(vm.theadStyles).toBe('width: 1985px;');
});
});
});
describe('methods', () => {
describe('handleEpicsListScroll', () => {
it('sets `scrolled-ahead` class on thead element based on provided scrollTop value', () => {
// vm.$el.clientHeight is 0 during tests
// hence any value greater than 0 should
// update scrolledHeaderClass prop
vm.handleEpicsListScroll(1);
expect(vm.scrolledHeaderClass).toBe('scrolled-ahead');
vm.handleEpicsListScroll(0);
expect(vm.scrolledHeaderClass).toBe('');
});
});
});
describe('mounted', () => {
it('binds `epicsListScrolled` event listener via eventHub', () => {
spyOn(eventHub, '$on');
const vmX = createComponent({});
expect(eventHub.$on).toHaveBeenCalledWith('epicsListScrolled', jasmine.any(Function));
vmX.$destroy();
});
});
describe('beforeDestroy', () => {
it('unbinds `epicsListScrolled` event listener via eventHub', () => {
spyOn(eventHub, '$off');
const vmX = createComponent({});
vmX.$destroy();
expect(eventHub.$off).toHaveBeenCalledWith('epicsListScrolled', jasmine.any(Function));
});
});
describe('template', () => {
it('renders component container element with class `roadmap-timeline-section`', () => {
expect(vm.$el.classList.contains('roadmap-timeline-section')).toBe(true);
});
it('renders empty header cell element with class `timeline-header-blank`', () => {
expect(vm.$el.querySelector('.timeline-header-blank')).not.toBeNull();
});
});
});
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