Commit 622f810e authored by Filipa Lacerda's avatar Filipa Lacerda

Merge branch 'mw-productivity-analytics-daterange-refactor' into 'master'

Productivity Analytics: Move daterange component to shared space

See merge request gitlab-org/gitlab!18383
parents 9421ee72 1fd8eb97
import Vue from 'vue';
import { mapState, mapActions } from 'vuex';
import { getDateInPast } from '~/lib/utils/datetime_utility';
import { defaultDaysInPast } from './constants';
import store from './store';
import FilterDropdowns from './components/filter_dropdowns.vue';
import DateRange from './components/daterange.vue';
import DateRange from '../shared/components/daterange.vue';
import ProductivityAnalyticsApp from './components/app.vue';
import FilteredSearchProductivityAnalytics from './filtered_search_productivity_analytics';
import { getLabelsEndpoint, getMilestonesEndpoint } from './utils';
......@@ -18,6 +21,10 @@ export default () => {
const { endpoint, emptyStateSvgPath, noAccessSvgPath } = appContainer.dataset;
const now = new Date(Date.now());
const defaultStartDate = new Date(getDateInPast(now, defaultDaysInPast));
const defaultEndDate = now;
let filterManager;
// eslint-disable-next-line no-new
......@@ -70,8 +77,31 @@ export default () => {
new Vue({
el: timeframeContainer,
store,
computed: {
...mapState('filters', ['groupNamespace', 'startDate', 'endDate']),
},
mounted() {
// let's not fetch data since we might not have a groupNamespace selected yet
// this just populates the store with the initial data and waits for a groupNamespace to be set
this.setDateRange({ startDate: defaultStartDate, endDate: defaultEndDate, skipFetch: true });
},
methods: {
...mapActions('filters', ['setDateRange']),
onDateRangeChange({ startDate, endDate }) {
this.setDateRange({ startDate, endDate });
},
},
render(h) {
return h(DateRange, {});
return h(DateRange, {
props: {
show: this.groupNamespace !== null,
startDate: defaultStartDate,
endDate: defaultEndDate,
},
on: {
change: this.onDateRangeChange,
},
});
},
});
......
<script>
import { mapState, mapActions } from 'vuex';
import { GlDaterangePicker } from '@gitlab/ui';
import { getDateInPast } from '~/lib/utils/datetime_utility';
import { defaultDaysInPast } from '../constants';
export default {
components: {
GlDaterangePicker,
},
props: {
show: {
type: Boolean,
required: false,
default: true,
},
startDate: {
type: Date,
required: false,
default: null,
},
endDate: {
type: Date,
required: false,
default: null,
},
},
computed: {
...mapState('filters', ['groupNamespace', 'startDate', 'endDate']),
dateRange: {
get() {
return { startDate: this.startDate, endDate: this.endDate };
},
set({ startDate, endDate }) {
this.setDateRange({ startDate, endDate });
this.$emit('change', { startDate, endDate });
},
},
},
mounted() {
this.initDateRange();
},
methods: {
...mapActions('filters', ['setDateRange']),
initDateRange() {
const endDate = new Date(Date.now());
const startDate = new Date(getDateInPast(endDate, defaultDaysInPast));
// let's not fetch data since we might not have a groupNamespace selected yet
// this just populates the store with the initial data and waits for a groupNamespace to be set
this.setDateRange({ skipFetch: true, startDate, endDate });
},
},
};
</script>
<template>
<div
v-if="groupNamespace"
v-if="show"
class="daterange-container d-flex flex-column flex-lg-row align-items-lg-center justify-content-lg-end"
>
<gl-daterange-picker
......
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
import AxiosMockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import Daterange from 'ee/analytics/productivity_analytics/components/daterange.vue';
import store from 'ee/analytics/productivity_analytics/store';
import { shallowMount } from '@vue/test-utils';
import Daterange from 'ee/analytics/shared/components/daterange.vue';
import { GlDaterangePicker } from '@gitlab/ui';
import resetStore from '../helpers';
const localVue = createLocalVue();
localVue.use(Vuex);
const startDate = new Date(2019, 8, 1);
const endDate = new Date(2019, 8, 11);
const groupNamespace = 'gitlab-org';
const defaultProps = {
startDate: new Date(2019, 8, 1),
endDate: new Date(2019, 8, 11),
};
describe('Daterange component', () => {
let wrapper;
let axiosMock;
const actionSpies = {
setDateRange: jest.fn(),
};
const factory = (props = {}) => {
wrapper = shallowMount(localVue.extend(Daterange), {
localVue,
store,
sync: false,
propsData: { ...props },
methods: {
...actionSpies,
const factory = (props = defaultProps) => {
wrapper = shallowMount(Daterange, {
propsData: {
...defaultProps,
...props,
},
});
};
beforeEach(() => {
axiosMock = new AxiosMockAdapter(axios);
axiosMock.onGet(store.state.endpoint).reply(200);
jest.spyOn(global.Date, 'now').mockImplementation(() => new Date('2019-09-25T00:00:00Z'));
factory();
});
afterEach(() => {
wrapper.destroy();
resetStore(store);
axiosMock.restore();
});
const findDaterangePicker = () => wrapper.find(GlDaterangePicker);
describe('template', () => {
describe('when there is no groupNamespace set', () => {
describe('when show is false', () => {
it('does not render the daterange picker', () => {
factory({ show: false });
expect(findDaterangePicker().exists()).toBe(false);
});
});
describe('when a groupNamespace is set', () => {
beforeEach(() => {
store.state.filters.groupNamespace = groupNamespace;
});
describe('when show is true', () => {
it('renders the daterange picker', () => {
factory({ show: true });
expect(findDaterangePicker().exists()).toBe(true);
});
});
});
describe('mounted', () => {
describe('initDateRange', () => {
it('dispatches setDateRange with skipFetch=true', () => {
expect(actionSpies.setDateRange).toHaveBeenCalledWith({
skipFetch: true,
startDate: new Date('2019-08-26T00:00:00.000Z'),
endDate: new Date('2019-09-25T00:00:00.000Z'),
});
});
});
});
describe('computed', () => {
describe('dateRange', () => {
beforeEach(() => {
store.state.filters.groupNamespace = groupNamespace;
factory({ show: true });
});
describe('dateRange', () => {
describe('set', () => {
it('calls `setDateRange` with an object containing startDate and endDate', () => {
it('emits the change event with an object containing startDate and endDate', () => {
const startDate = new Date('2019-10-01');
const endDate = new Date('2019-10-05');
wrapper.vm.dateRange = { startDate, endDate };
expect(actionSpies.setDateRange).toHaveBeenCalledWith({ startDate, endDate });
expect(wrapper.emittedByOrder()).toEqual([
{
name: 'change',
args: [{ startDate, endDate }],
},
]);
});
});
describe('get', () => {
beforeEach(() => {
store.state.filters.startDate = startDate;
store.state.filters.endDate = endDate;
});
it("returns value of dateRange from state's startDate and endDate", () => {
expect(wrapper.vm.dateRange).toEqual({ startDate, endDate });
expect(wrapper.vm.dateRange).toEqual({
startDate: defaultProps.startDate,
endDate: defaultProps.endDate,
});
});
});
});
......
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