Commit eadb8489 authored by Brandon Labuschagne's avatar Brandon Labuschagne Committed by Jacques Erasmus

Replace Contribution Analytics bootstrap dropdown with Vue component

parent efe2bedd
<script>
import { GlSegmentedControl } from '@gitlab/ui';
import { mergeUrlParams, redirectTo, getParameterByName } from '~/lib/utils/url_utility';
import { DATE_OPTIONS } from '../constants';
export default {
name: 'DateSelector',
dateOptions: DATE_OPTIONS,
components: {
GlSegmentedControl,
},
inject: {
path: {
default: '',
},
},
data() {
return {
selectedDateOption: getParameterByName('start_date') || DATE_OPTIONS[0].value,
};
},
methods: {
loadPageWithDate(date) {
redirectTo(mergeUrlParams({ start_date: date }, this.path));
},
},
};
</script>
<template>
<gl-segmented-control
:checked="selectedDateOption"
:options="$options.dateOptions"
@change="loadPageWithDate"
/>
</template>
import dateFormat from 'dateformat';
import { dateFormats } from '~/analytics/shared/constants';
import { getDateInPast, nMonthsBefore } from '~/lib/utils/datetime_utility';
import { s__ } from '~/locale';
export const CHART_HEIGHT = 350;
export const INNER_CHART_HEIGHT = 200;
export const CHART_X_AXIS_ROTATE = 45;
export const CHART_X_AXIS_NAME_TOP_PADDING = 55;
export const DATE_OPTIONS = [
{
text: s__('ContributionAnalytics|Last week'),
value: dateFormat(getDateInPast(new Date(), 7), dateFormats.isoDate),
},
{
text: s__('ContributionAnalytics|Last month'),
value: dateFormat(nMonthsBefore(new Date(), 1), dateFormats.isoDate),
},
{
text: s__('ContributionAnalytics|Last 3 months'),
value: dateFormat(nMonthsBefore(new Date(), 3), dateFormats.isoDate),
},
];
......@@ -2,6 +2,7 @@ import { sortBy } from 'lodash';
import Vue from 'vue';
import { __ } from '~/locale';
import ColumnChart from './components/column_chart.vue';
import DateSelector from './components/date_selector.vue';
const sortByValue = (data) => sortBy(data, (item) => item[1]).reverse();
......@@ -29,6 +30,25 @@ export default (dataEl) => {
});
});
const dateSelectorEl = document.querySelector('.js-contribution-analytics-date-selector');
if (dateSelectorEl) {
const { path } = dateSelectorEl.dataset;
// eslint-disable-next-line no-new
new Vue({
el: dateSelectorEl,
components: {
DateSelector,
},
provide: {
path,
},
render(h) {
return h(DateSelector);
},
});
}
const pushesEl = document.getElementById('js_pushes_chart_vue');
if (allValuesEmpty(formattedData.push)) {
// eslint-disable-next-line no-new
......
......@@ -5,24 +5,9 @@
%h3
= _('Contribution Analytics')
.sub-header-block
.float-right
.dropdown.inline
%button.gl-button.dropdown-toggle.btn.gl-text-gray-500{ type: 'button', 'data-toggle' => 'dropdown' }
= sprite_icon('calendar')
%b.caret
%ul.dropdown-menu.dropdown-menu-right
%li
= link_to group_contribution_analytics_path(@group, start_date: Date.today - 1.week) do
= s_('ContributionAnalytics|Last week')
%li
= link_to group_contribution_analytics_path(@group, start_date: Date.today - 1.month) do
= s_('ContributionAnalytics|Last month')
%li
= link_to group_contribution_analytics_path(@group, start_date: Date.today - 3.months) do
= s_('ContributionAnalytics|Last 3 months')
.oneline
.sub-header-block.gl-display-flex.gl-justify-content-space-between.gl-align-items-center
= s_('ContributionAnalytics|Contribution analytics for issues, merge requests and push events since %{start_date}') % { start_date: @start_date }
.js-contribution-analytics-date-selector{ data: { path: group_contribution_analytics_path } }
%div{ data: { qa_selector: 'push_content' } }
%h3= _('Pushes')
......
import { GlSegmentedControl } from '@gitlab/ui';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
import * as urlUtils from '~/lib/utils/url_utility';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import DateSelector from 'ee/analytics/contribution_analytics/components/date_selector.vue';
import { DATE_OPTIONS } from 'ee/analytics/contribution_analytics/constants';
const path = 'http://path.path';
describe('DateSelector', () => {
let wrapper;
const createComponent = () => {
wrapper = shallowMountExtended(DateSelector, {
provide: {
path,
},
});
};
const findSegmentControl = () => wrapper.findComponent(GlSegmentedControl);
afterEach(() => {
wrapper.destroy();
});
it('displays the segmented control component', () => {
createComponent();
expect(findSegmentControl().exists()).toBe(true);
});
it('contains the correct segmented control items', () => {
createComponent();
expect(findSegmentControl().props('options')).toEqual(DATE_OPTIONS);
});
describe('on item click', () => {
useMockLocationHelper();
beforeEach(() => {
jest.spyOn(urlUtils, 'getParameterByName').mockReturnValue('1234');
createComponent();
});
it.each(DATE_OPTIONS)('redirects to the correct URL', ({ value }) => {
const spy = jest.spyOn(urlUtils, 'redirectTo');
findSegmentControl().vm.$emit('change', value);
expect(spy).toHaveBeenCalledWith(`${path}?start_date=${value}`);
});
});
describe.each(DATE_OPTIONS)('default selected option', ({ value }) => {
beforeEach(() => {
jest.spyOn(urlUtils, 'getParameterByName').mockReturnValue(value);
createComponent();
});
it('sets the correct selected option', () => {
expect(findSegmentControl().props('checked')).toBe(value);
});
});
});
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