Commit 58580ae9 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '13216-implement-a-date-picker-for-cycle-analytics' into 'master'

Resolve "Implement a date picker for cycle analytics"

Closes #13216

See merge request gitlab-org/gitlab!16510
parents f560fedd 5ff67e3a
<script> <script>
import { GlEmptyState } from '@gitlab/ui'; import { GlEmptyState, GlDaterangePicker } from '@gitlab/ui';
import { mapActions, mapState, mapGetters } from 'vuex'; import { mapActions, mapState, mapGetters } from 'vuex';
import { getDateInPast } from '~/lib/utils/datetime_utility';
import { featureAccessLevel } from '~/pages/projects/shared/permissions/constants'; import { featureAccessLevel } from '~/pages/projects/shared/permissions/constants';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { PROJECTS_PER_PAGE } from '../constants'; import { PROJECTS_PER_PAGE, DEFAULT_DAYS_IN_PAST } from '../constants';
import GroupsDropdownFilter from '../../shared/components/groups_dropdown_filter.vue'; import GroupsDropdownFilter from '../../shared/components/groups_dropdown_filter.vue';
import ProjectsDropdownFilter from '../../shared/components/projects_dropdown_filter.vue'; import ProjectsDropdownFilter from '../../shared/components/projects_dropdown_filter.vue';
import DateRangeDropdown from '../../shared/components/date_range_dropdown.vue';
import SummaryTable from './summary_table.vue'; import SummaryTable from './summary_table.vue';
import StageTable from './stage_table.vue'; import StageTable from './stage_table.vue';
...@@ -16,9 +16,9 @@ export default { ...@@ -16,9 +16,9 @@ export default {
GlEmptyState, GlEmptyState,
GroupsDropdownFilter, GroupsDropdownFilter,
ProjectsDropdownFilter, ProjectsDropdownFilter,
DateRangeDropdown,
SummaryTable, SummaryTable,
StageTable, StageTable,
GlDaterangePicker,
}, },
mixins: [glFeatureFlagsMixin()], mixins: [glFeatureFlagsMixin()],
props: { props: {
...@@ -61,11 +61,12 @@ export default { ...@@ -61,11 +61,12 @@ export default {
'selectedStageName', 'selectedStageName',
'stages', 'stages',
'summary', 'summary',
'dataTimeframe',
'labels', 'labels',
'currentStageEvents', 'currentStageEvents',
'customStageFormEvents', 'customStageFormEvents',
'errorCode', 'errorCode',
'startDate',
'endDate',
]), ]),
...mapGetters(['currentStage', 'defaultStage', 'hasNoAccessError', 'currentGroupPath']), ...mapGetters(['currentStage', 'defaultStage', 'hasNoAccessError', 'currentGroupPath']),
shouldRenderEmptyState() { shouldRenderEmptyState() {
...@@ -77,6 +78,17 @@ export default { ...@@ -77,6 +78,17 @@ export default {
shouldDisplayFilters() { shouldDisplayFilters() {
return this.selectedGroup && !this.errorCode; return this.selectedGroup && !this.errorCode;
}, },
dateRange: {
get() {
return { startDate: this.startDate, endDate: this.endDate };
},
set({ startDate, endDate }) {
this.setDateRange({ startDate, endDate });
},
},
},
mounted() {
this.initDateRange();
}, },
methods: { methods: {
...mapActions([ ...mapActions([
...@@ -88,8 +100,10 @@ export default { ...@@ -88,8 +100,10 @@ export default {
'setSelectedGroup', 'setSelectedGroup',
'setSelectedProjects', 'setSelectedProjects',
'setSelectedTimeframe', 'setSelectedTimeframe',
'fetchStageData',
'setSelectedStageName', 'setSelectedStageName',
'hideCustomStageForm', 'hideCustomStageForm',
'setDateRange',
]), ]),
onGroupSelect(group) { onGroupSelect(group) {
this.setCycleAnalyticsDataEndpoint(group.path); this.setCycleAnalyticsDataEndpoint(group.path);
...@@ -101,10 +115,6 @@ export default { ...@@ -101,10 +115,6 @@ export default {
this.setSelectedProjects(projectIds); this.setSelectedProjects(projectIds);
this.fetchCycleAnalyticsData(); this.fetchCycleAnalyticsData();
}, },
onTimeframeSelect(days) {
this.setSelectedTimeframe(days);
this.fetchCycleAnalyticsData();
},
onStageSelect(stage) { onStageSelect(stage) {
this.hideCustomStageForm(); this.hideCustomStageForm();
this.setSelectedStageName(stage.name); this.setSelectedStageName(stage.name);
...@@ -114,6 +124,11 @@ export default { ...@@ -114,6 +124,11 @@ export default {
onShowAddStageForm() { onShowAddStageForm() {
this.fetchCustomStageFormData(this.currentGroupPath); this.fetchCustomStageFormData(this.currentGroupPath);
}, },
initDateRange() {
const endDate = new Date(Date.now());
const startDate = new Date(getDateInPast(endDate, DEFAULT_DAYS_IN_PAST));
this.setDateRange({ skipFetch: true, startDate, endDate });
},
}, },
}; };
</script> </script>
...@@ -145,12 +160,14 @@ export default { ...@@ -145,12 +160,14 @@ export default {
v-if="shouldDisplayFilters" v-if="shouldDisplayFilters"
class="ml-0 ml-md-auto mt-2 mt-md-0 d-flex flex-column flex-md-row align-items-md-center justify-content-md-end" class="ml-0 ml-md-auto mt-2 mt-md-0 d-flex flex-column flex-md-row align-items-md-center justify-content-md-end"
> >
<label class="text-bold mb-0 mr-1">{{ __('Timeframe') }}</label> <gl-daterange-picker
<date-range-dropdown v-model="dateRange"
class="js-timeframe-filter" class="d-flex flex-column flex-lg-row js-daterange-picker"
:available-days-in-past="dateOptions" :default-start-date="startDate"
:default-selected="dataTimeframe" :default-end-date="endDate"
@selected="onTimeframeSelect" start-picker-class="d-flex flex-column flex-lg-row align-items-lg-center mr-lg-2"
end-picker-class="d-flex flex-column flex-lg-row align-items-lg-center"
theme="animate-picker"
/> />
</div> </div>
</div> </div>
......
...@@ -2,7 +2,7 @@ import { __ } from '~/locale'; ...@@ -2,7 +2,7 @@ import { __ } from '~/locale';
export const PROJECTS_PER_PAGE = 50; export const PROJECTS_PER_PAGE = 50;
export const DEFAULT_DATA_TIME_FRAME = 30; export const DEFAULT_DAYS_IN_PAST = 30;
export const EVENTS_LIST_ITEM_LIMIT = 50; export const EVENTS_LIST_ITEM_LIMIT = 50;
......
import dateFormat from 'dateformat';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import createFlash from '~/flash'; import createFlash from '~/flash';
import { __ } from '~/locale'; import { __ } from '~/locale';
import Api from '~/api'; import Api from '~/api';
import httpStatus from '~/lib/utils/http_status'; import httpStatus from '~/lib/utils/http_status';
import * as types from './mutation_types'; import * as types from './mutation_types';
import { dateFormats } from '../../shared/constants';
export const setCycleAnalyticsDataEndpoint = ({ commit }, groupPath) => export const setCycleAnalyticsDataEndpoint = ({ commit }, groupPath) =>
commit(types.SET_CYCLE_ANALYTICS_DATA_ENDPOINT, groupPath); commit(types.SET_CYCLE_ANALYTICS_DATA_ENDPOINT, groupPath);
...@@ -13,11 +15,20 @@ export const setStageDataEndpoint = ({ commit }, stageSlug) => ...@@ -13,11 +15,20 @@ export const setStageDataEndpoint = ({ commit }, stageSlug) =>
export const setSelectedGroup = ({ commit }, group) => commit(types.SET_SELECTED_GROUP, group); export const setSelectedGroup = ({ commit }, group) => commit(types.SET_SELECTED_GROUP, group);
export const setSelectedProjects = ({ commit }, projectIds) => export const setSelectedProjects = ({ commit }, projectIds) =>
commit(types.SET_SELECTED_PROJECTS, projectIds); commit(types.SET_SELECTED_PROJECTS, projectIds);
export const setSelectedTimeframe = ({ commit }, timeframe) =>
commit(types.SET_SELECTED_TIMEFRAME, timeframe);
export const setSelectedStageName = ({ commit }, stageName) => export const setSelectedStageName = ({ commit }, stageName) =>
commit(types.SET_SELECTED_STAGE_NAME, stageName); commit(types.SET_SELECTED_STAGE_NAME, stageName);
export const setDateRange = (
{ commit, dispatch, state },
{ skipFetch = false, startDate, endDate },
) => {
commit(types.SET_DATE_RANGE, { startDate, endDate });
if (skipFetch) return false;
return dispatch('fetchCycleAnalyticsData', { state, dispatch });
};
export const requestStageData = ({ commit }) => commit(types.REQUEST_STAGE_DATA); export const requestStageData = ({ commit }) => commit(types.REQUEST_STAGE_DATA);
export const receiveStageDataSuccess = ({ commit }, data) => export const receiveStageDataSuccess = ({ commit }, data) =>
commit(types.RECEIVE_STAGE_DATA_SUCCESS, data); commit(types.RECEIVE_STAGE_DATA_SUCCESS, data);
...@@ -33,7 +44,8 @@ export const fetchStageData = ({ state, dispatch }) => { ...@@ -33,7 +44,8 @@ export const fetchStageData = ({ state, dispatch }) => {
axios axios
.get(state.endpoints.stageData, { .get(state.endpoints.stageData, {
params: { params: {
'cycle_analytics[start_date]': state.dataTimeframe, 'cycle_analytics[created_after]': dateFormat(state.startDate, dateFormats.isoDate),
'cycle_analytics[created_before]': dateFormat(state.endDate, dateFormats.isoDate),
'cycle_analytics[project_ids]': state.selectedProjectIds, 'cycle_analytics[project_ids]': state.selectedProjectIds,
}, },
}) })
...@@ -68,7 +80,8 @@ export const fetchCycleAnalyticsData = ({ state, dispatch }) => { ...@@ -68,7 +80,8 @@ export const fetchCycleAnalyticsData = ({ state, dispatch }) => {
axios axios
.get(state.endpoints.cycleAnalyticsData, { .get(state.endpoints.cycleAnalyticsData, {
params: { params: {
'cycle_analytics[start_date]': state.dataTimeframe, 'cycle_analytics[created_after]': dateFormat(state.startDate, dateFormats.isoDate),
'cycle_analytics[created_before]': dateFormat(state.endDate, dateFormats.isoDate),
'cycle_analytics[project_ids]': state.selectedProjectIds, 'cycle_analytics[project_ids]': state.selectedProjectIds,
}, },
}) })
......
...@@ -3,9 +3,10 @@ export const SET_STAGE_DATA_ENDPOINT = 'SET_STAGE_DATA_ENDPOINT'; ...@@ -3,9 +3,10 @@ export const SET_STAGE_DATA_ENDPOINT = 'SET_STAGE_DATA_ENDPOINT';
export const SET_SELECTED_GROUP = 'SET_SELECTED_GROUP'; export const SET_SELECTED_GROUP = 'SET_SELECTED_GROUP';
export const SET_SELECTED_PROJECTS = 'SET_SELECTED_PROJECTS'; export const SET_SELECTED_PROJECTS = 'SET_SELECTED_PROJECTS';
export const SET_SELECTED_TIMEFRAME = 'SET_SELECTED_TIMEFRAME';
export const SET_SELECTED_STAGE_NAME = 'SET_SELECTED_STAGE_NAME'; export const SET_SELECTED_STAGE_NAME = 'SET_SELECTED_STAGE_NAME';
export const SET_DATE_RANGE = 'SET_DATE_RANGE';
export const REQUEST_CYCLE_ANALYTICS_DATA = 'REQUEST_CYCLE_ANALYTICS_DATA'; export const REQUEST_CYCLE_ANALYTICS_DATA = 'REQUEST_CYCLE_ANALYTICS_DATA';
export const RECEIVE_CYCLE_ANALYTICS_DATA_SUCCESS = 'RECEIVE_CYCLE_ANALYTICS_DATA_SUCCESS'; export const RECEIVE_CYCLE_ANALYTICS_DATA_SUCCESS = 'RECEIVE_CYCLE_ANALYTICS_DATA_SUCCESS';
export const RECEIVE_CYCLE_ANALYTICS_DATA_ERROR = 'RECEIVE_CYCLE_ANALYTICS_DATA_ERROR'; export const RECEIVE_CYCLE_ANALYTICS_DATA_ERROR = 'RECEIVE_CYCLE_ANALYTICS_DATA_ERROR';
......
...@@ -17,12 +17,13 @@ export default { ...@@ -17,12 +17,13 @@ export default {
[types.SET_SELECTED_PROJECTS](state, projectIds) { [types.SET_SELECTED_PROJECTS](state, projectIds) {
state.selectedProjectIds = projectIds; state.selectedProjectIds = projectIds;
}, },
[types.SET_SELECTED_TIMEFRAME](state, timeframe) {
state.dataTimeframe = timeframe;
},
[types.SET_SELECTED_STAGE_NAME](state, stageName) { [types.SET_SELECTED_STAGE_NAME](state, stageName) {
state.selectedStageName = stageName; state.selectedStageName = stageName;
}, },
[types.SET_DATE_RANGE](state, { startDate, endDate }) {
state.startDate = startDate;
state.endDate = endDate;
},
[types.REQUEST_CYCLE_ANALYTICS_DATA](state) { [types.REQUEST_CYCLE_ANALYTICS_DATA](state) {
state.isLoading = true; state.isLoading = true;
state.isAddingCustomStage = false; state.isAddingCustomStage = false;
......
import { DEFAULT_DATA_TIME_FRAME } from '../constants';
export default () => ({ export default () => ({
endpoints: { endpoints: {
cycleAnalyticsData: '', cycleAnalyticsData: null,
stageData: '', stageData: null,
}, },
dataTimeframe: DEFAULT_DATA_TIME_FRAME, startDate: null,
endDate: null,
isLoading: false, isLoading: false,
isLoadingStage: false, isLoadingStage: false,
......
.gl-daterange-picker {
.gl-datepicker-input {
width: 140px;
@include media-breakpoint-down(md) {
width: 100%;
}
}
label {
@include media-breakpoint-up(lg) {
margin-bottom: 0;
margin-right: $gl-padding-4;
}
}
}
...@@ -47,7 +47,7 @@ describe 'Group Cycle Analytics', :js do ...@@ -47,7 +47,7 @@ describe 'Group Cycle Analytics', :js do
end end
it 'shows the date filter' do it 'shows the date filter' do
expect(page).to have_selector('.js-timeframe-filter', visible: true) expect(page).to have_selector('.js-daterange-picker', visible: true)
end end
end end
......
...@@ -3,12 +3,11 @@ import Vuex from 'vuex'; ...@@ -3,12 +3,11 @@ import Vuex from 'vuex';
import Vue from 'vue'; import Vue from 'vue';
import store from 'ee/analytics/cycle_analytics/store'; import store from 'ee/analytics/cycle_analytics/store';
import Component from 'ee/analytics/cycle_analytics/components/base.vue'; import Component from 'ee/analytics/cycle_analytics/components/base.vue';
import { GlEmptyState } from '@gitlab/ui'; import { GlEmptyState, GlDaterangePicker } from '@gitlab/ui';
import axios from 'axios'; import axios from 'axios';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import GroupsDropdownFilter from 'ee/analytics/shared/components/groups_dropdown_filter.vue'; import GroupsDropdownFilter from 'ee/analytics/shared/components/groups_dropdown_filter.vue';
import ProjectsDropdownFilter from 'ee/analytics/shared/components/projects_dropdown_filter.vue'; import ProjectsDropdownFilter from 'ee/analytics/shared/components/projects_dropdown_filter.vue';
import DateRangeDropdown from 'ee/analytics/shared/components/date_range_dropdown.vue';
import SummaryTable from 'ee/analytics/cycle_analytics/components/summary_table.vue'; import SummaryTable from 'ee/analytics/cycle_analytics/components/summary_table.vue';
import StageTable from 'ee/analytics/cycle_analytics/components/stage_table.vue'; import StageTable from 'ee/analytics/cycle_analytics/components/stage_table.vue';
import 'bootstrap'; import 'bootstrap';
...@@ -66,8 +65,8 @@ describe('Cycle Analytics component', () => { ...@@ -66,8 +65,8 @@ describe('Cycle Analytics component', () => {
expect(wrapper.find(ProjectsDropdownFilter).exists()).toBe(flag); expect(wrapper.find(ProjectsDropdownFilter).exists()).toBe(flag);
}; };
const displaysDateRangeDropdown = flag => { const displaysDateRangePicker = flag => {
expect(wrapper.find(DateRangeDropdown).exists()).toBe(flag); expect(wrapper.find(GlDaterangePicker).exists()).toBe(flag);
}; };
const displaysSummaryTable = flag => { const displaysSummaryTable = flag => {
...@@ -88,6 +87,27 @@ describe('Cycle Analytics component', () => { ...@@ -88,6 +87,27 @@ describe('Cycle Analytics component', () => {
mock.restore(); mock.restore();
}); });
describe('mounted', () => {
const actionSpies = {
setDateRange: jest.fn(),
};
beforeEach(() => {
jest.spyOn(global.Date, 'now').mockImplementation(() => new Date(mockData.endDate));
wrapper = createComponent({ opts: { methods: actionSpies } });
});
describe('initDateRange', () => {
it('dispatches setDateRange with skipFetch=true', () => {
expect(actionSpies.setDateRange).toHaveBeenCalledWith({
skipFetch: true,
startDate: mockData.startDate,
endDate: mockData.endDate,
});
});
});
});
describe('displays the components as required', () => { describe('displays the components as required', () => {
describe('before a filter has been selected', () => { describe('before a filter has been selected', () => {
it('displays an empty state', () => { it('displays an empty state', () => {
...@@ -108,8 +128,8 @@ describe('Cycle Analytics component', () => { ...@@ -108,8 +128,8 @@ describe('Cycle Analytics component', () => {
displaysProjectsDropdownFilter(false); displaysProjectsDropdownFilter(false);
}); });
it('does not display the date range dropdown', () => { it('does not display the date range picker', () => {
displaysDateRangeDropdown(false); displaysDateRangePicker(false);
}); });
it('does not display the summary table', () => { it('does not display the summary table', () => {
...@@ -143,8 +163,8 @@ describe('Cycle Analytics component', () => { ...@@ -143,8 +163,8 @@ describe('Cycle Analytics component', () => {
); );
}); });
it('displays the date range dropdown', () => { it('displays the date range picker', () => {
displaysDateRangeDropdown(true); displaysDateRangePicker(true);
}); });
it('displays the summary table', () => { it('displays the summary table', () => {
...@@ -224,8 +244,8 @@ describe('Cycle Analytics component', () => { ...@@ -224,8 +244,8 @@ describe('Cycle Analytics component', () => {
displaysProjectsDropdownFilter(false); displaysProjectsDropdownFilter(false);
}); });
it('does not display the date range dropdown', () => { it('does not display the date range picker', () => {
displaysDateRangeDropdown(false); displaysDateRangePicker(false);
}); });
it('does not display the summary table', () => { it('does not display the summary table', () => {
......
...@@ -3,6 +3,8 @@ import { getJSONFixture } from 'helpers/fixtures'; ...@@ -3,6 +3,8 @@ import { getJSONFixture } from 'helpers/fixtures';
import mutations from 'ee/analytics/cycle_analytics/store/mutations'; import mutations from 'ee/analytics/cycle_analytics/store/mutations';
import * as types from 'ee/analytics/cycle_analytics/store/mutation_types'; import * as types from 'ee/analytics/cycle_analytics/store/mutation_types';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { getDateInPast } from '~/lib/utils/datetime_utility';
import { DEFAULT_DAYS_IN_PAST } from 'ee/analytics/cycle_analytics/constants';
import { mockLabels } from '../../../../../spec/javascripts/vue_shared/components/sidebar/labels_select/mock_data'; import { mockLabels } from '../../../../../spec/javascripts/vue_shared/components/sidebar/labels_select/mock_data';
export const groupLabels = mockLabels.map(({ title, ...rest }) => ({ ...rest, name: title })); export const groupLabels = mockLabels.map(({ title, ...rest }) => ({ ...rest, name: title }));
...@@ -47,6 +49,9 @@ const stageFixtures = defaultStages.reduce((acc, stage) => { ...@@ -47,6 +49,9 @@ const stageFixtures = defaultStages.reduce((acc, stage) => {
}; };
}, {}); }, {});
export const endDate = new Date(Date.now());
export const startDate = new Date(getDateInPast(endDate, DEFAULT_DAYS_IN_PAST));
export const issueEvents = stageFixtures.issue; export const issueEvents = stageFixtures.issue;
export const planEvents = stageFixtures.plan; export const planEvents = stageFixtures.plan;
export const reviewEvents = stageFixtures.review; export const reviewEvents = stageFixtures.review;
......
...@@ -4,7 +4,14 @@ import testAction from 'helpers/vuex_action_helper'; ...@@ -4,7 +4,14 @@ import testAction from 'helpers/vuex_action_helper';
import { TEST_HOST } from 'helpers/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
import * as actions from 'ee/analytics/cycle_analytics/store/actions'; import * as actions from 'ee/analytics/cycle_analytics/store/actions';
import * as types from 'ee/analytics/cycle_analytics/store/mutation_types'; import * as types from 'ee/analytics/cycle_analytics/store/mutation_types';
import { group, cycleAnalyticsData, allowedStages as stages, groupLabels } from '../mock_data'; import {
group,
cycleAnalyticsData,
allowedStages as stages,
groupLabels,
startDate,
endDate,
} from '../mock_data';
const stageData = { events: [] }; const stageData = { events: [] };
const error = new Error('Request failed with status code 404'); const error = new Error('Request failed with status code 404');
...@@ -41,7 +48,6 @@ describe('Cycle analytics actions', () => { ...@@ -41,7 +48,6 @@ describe('Cycle analytics actions', () => {
${'setSelectedGroup'} | ${'SET_SELECTED_GROUP'} | ${'selectedGroup'} | ${'someNewGroup'} ${'setSelectedGroup'} | ${'SET_SELECTED_GROUP'} | ${'selectedGroup'} | ${'someNewGroup'}
${'setSelectedProjects'} | ${'SET_SELECTED_PROJECTS'} | ${'selectedProjectIds'} | ${[10, 20, 30, 40]} ${'setSelectedProjects'} | ${'SET_SELECTED_PROJECTS'} | ${'selectedProjectIds'} | ${[10, 20, 30, 40]}
${'setSelectedStageName'} | ${'SET_SELECTED_STAGE_NAME'} | ${'selectedStageName'} | ${'someNewGroup'} ${'setSelectedStageName'} | ${'SET_SELECTED_STAGE_NAME'} | ${'selectedStageName'} | ${'someNewGroup'}
${'setSelectedTimeframe'} | ${'SET_SELECTED_TIMEFRAME'} | ${'dataTimeframe'} | ${20}
`('$action should set $stateKey with $payload and type $type', ({ action, type, payload }) => { `('$action should set $stateKey with $payload and type $type', ({ action, type, payload }) => {
testAction( testAction(
actions[action], actions[action],
...@@ -57,6 +63,21 @@ describe('Cycle analytics actions', () => { ...@@ -57,6 +63,21 @@ describe('Cycle analytics actions', () => {
); );
}); });
describe('setDateRange', () => {
it('sets the dates as expected and dispatches fetchCycleAnalyticsData', done => {
const dispatch = expect.any(Function);
testAction(
actions.setDateRange,
{ startDate, endDate },
state,
[{ type: types.SET_DATE_RANGE, payload: { startDate, endDate } }],
[{ type: 'fetchCycleAnalyticsData', payload: { dispatch, state } }],
done,
);
});
});
describe('fetchStageData', () => { describe('fetchStageData', () => {
beforeEach(() => { beforeEach(() => {
mock.onGet(state.endpoints.stageData).replyOnce(200, { events: [] }); mock.onGet(state.endpoints.stageData).replyOnce(200, { events: [] });
......
...@@ -13,6 +13,8 @@ import { ...@@ -13,6 +13,8 @@ import {
reviewStage, reviewStage,
productionStage, productionStage,
groupLabels, groupLabels,
startDate,
endDate,
} from '../mock_data'; } from '../mock_data';
let state = null; let state = null;
...@@ -45,13 +47,13 @@ describe('Cycle analytics mutations', () => { ...@@ -45,13 +47,13 @@ describe('Cycle analytics mutations', () => {
}); });
it.each` it.each`
mutation | payload | expectedState mutation | payload | expectedState
${types.SET_CYCLE_ANALYTICS_DATA_ENDPOINT} | ${'cool-beans'} | ${{ endpoints: { cycleAnalyticsData: '/groups/cool-beans/-/cycle_analytics' } }} ${types.SET_CYCLE_ANALYTICS_DATA_ENDPOINT} | ${'cool-beans'} | ${{ endpoints: { cycleAnalyticsData: '/groups/cool-beans/-/cycle_analytics' } }}
${types.SET_STAGE_DATA_ENDPOINT} | ${'rad-stage'} | ${{ endpoints: { stageData: '/fake/api/events/rad-stage.json' } }} ${types.SET_STAGE_DATA_ENDPOINT} | ${'rad-stage'} | ${{ endpoints: { stageData: '/fake/api/events/rad-stage.json' } }}
${types.SET_SELECTED_GROUP} | ${'cool-beans'} | ${{ selectedGroup: 'cool-beans', selectedProjectIds: [] }} ${types.SET_SELECTED_GROUP} | ${'cool-beans'} | ${{ selectedGroup: 'cool-beans', selectedProjectIds: [] }}
${types.SET_SELECTED_PROJECTS} | ${[606, 707, 808, 909]} | ${{ selectedProjectIds: [606, 707, 808, 909] }} ${types.SET_SELECTED_PROJECTS} | ${[606, 707, 808, 909]} | ${{ selectedProjectIds: [606, 707, 808, 909] }}
${types.SET_SELECTED_TIMEFRAME} | ${60} | ${{ dataTimeframe: 60 }} ${types.SET_DATE_RANGE} | ${{ startDate, endDate }} | ${{ startDate, endDate }}
${types.SET_SELECTED_STAGE_NAME} | ${'first-stage'} | ${{ selectedStageName: 'first-stage' }} ${types.SET_SELECTED_STAGE_NAME} | ${'first-stage'} | ${{ selectedStageName: 'first-stage' }}
`( `(
'$mutation with payload $payload will update state with $expectedState', '$mutation with payload $payload will update state with $expectedState',
({ mutation, payload, expectedState }) => { ({ mutation, payload, expectedState }) => {
......
...@@ -16674,9 +16674,6 @@ msgstr "" ...@@ -16674,9 +16674,6 @@ msgstr ""
msgid "Timeago|right now" msgid "Timeago|right now"
msgstr "" msgstr ""
msgid "Timeframe"
msgstr ""
msgid "Timeout" msgid "Timeout"
msgstr "" msgstr ""
......
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