Commit 5af819b7 authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Fetch tasks_by_type data

Adds basic vuex boilerplate for fetching
the tasks_by_type chart data for cycle
analytics
parent 048b0453
......@@ -100,11 +100,13 @@ export default {
'showCustomStageForm',
'setDateRange',
'createCustomStage',
'fetchTasksByTypeData',
]),
onGroupSelect(group) {
this.setCycleAnalyticsDataEndpoint(group.full_path);
this.setSelectedGroup(group);
this.fetchCycleAnalyticsData();
this.fetchTasksByTypeData(group.path);
},
onProjectsSelect(projects) {
const projectIds = projects.map(value => value.id);
......
......@@ -29,3 +29,6 @@ export const EMPTY_STAGE_TEXT = {
'The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.',
),
};
export const TASKS_BY_TYPE_SUBJECT_ISSUE = 'issues';
export const TASKS_BY_TYPE_SUBJECT_MERGE_REQUEST = 'merge_requests';
......@@ -199,15 +199,41 @@ export const receiveTasksByTypeError = ({ commit }, error) => {
commit(types.RECEIVE_TASKS_BY_TYPE_ERROR, error);
createFlash(__('There was an error fetching data for the form'));
};
export const requestTasksByType = ({ commit }) => commit(types.REQUEST_TASKS_BY_TYPE);
export const fetchTasksByType = ({ dispatch }, { groupPath, labelIds }) => {
const endpoint = '/~/analytics/tasks_by_type';
const params = { group_id: groupPath, label_ids: labelIds };
dispatch('requestTasksByTypeData');
export const receiveTasksByTypeDataSuccess = ({ commit }, data) =>
commit(types.RECEIVE_TASKS_BY_TYPE_DATA_SUCCESS, data);
export const receiveTasksByTypeDataError = ({ commit }, error) => {
commit(types.RECEIVE_TASKS_BY_TYPE_DATA_ERROR, error);
createFlash(__('There was an error fetching data for the chart'));
};
export const requestTasksByTypeData = ({ commit }) => commit(types.REQUEST_TASKS_BY_TYPE_DATA);
return axios
.get(endpoint, params)
.then(data => dispatch('receiveTasksByTypeSuccess', data))
.catch(error => dispatch('receiveTasksByTypeError', error));
export const fetchTasksByTypeData = ({ dispatch, state }, groupPath) => {
const endpoint = '/-/analytics/type_of_work/tasks_by_type';
const {
tasksByType: { labelIds, subject },
selectedProjectIds,
timeFrameCreatedBefore,
timeFrameCreatedAfter,
} = state;
// dont request if we have no labels selected...for now
if (!labelIds.length) {
const params = {
group_id: groupPath,
label_ids: labelIds,
project_ids: selectedProjectIds,
created_before: timeFrameCreatedBefore,
created_after: timeFrameCreatedAfter,
subject,
};
dispatch('requestTasksByTypeData');
// TODO: move to service / api
return axios
.get(endpoint, { params })
.then(data => dispatch('receiveTasksByTypeDataSuccess', data))
.catch(error => dispatch('receiveTasksByTypeDataError', error));
}
};
......@@ -33,6 +33,11 @@ export const RECEIVE_GROUP_STAGES_AND_EVENTS_ERROR = 'RECEIVE_GROUP_STAGES_AND_E
export const REQUEST_CREATE_CUSTOM_STAGE = 'REQUEST_CREATE_CUSTOM_STAGE';
export const RECEIVE_CREATE_CUSTOM_STAGE_RESPONSE = 'RECEIVE_CREATE_CUSTOM_STAGE_RESPONSE';
export const SET_TASKS_BY_TYPE_SUBJECT = 'SET_TASKS_BY_TYPE_SUBJECT';
export const SET_TASKS_BY_TYPE_LABELS = 'SET_TASKS_BY_TYPE_LABELS';
export const REQUEST_TASKS_BY_TYPE_DATA = 'REQUEST_TASKS_BY_TYPE_DATA';
export const RECEIVE_TASKS_BY_TYPE_DATA_SUCCESS = 'RECEIVE_TASKS_BY_TYPE_DATA_SUCCESS';
export const RECEIVE_TASKS_BY_TYPE_DATA_ERROR = 'RECEIVE_TASKS_BY_TYPE_DATA_ERROR';
export const SET_TIMEFRAME_START_AND_END = 'SET_TIMEFRAME_START_AND_END';
......@@ -126,7 +126,55 @@ export default {
[types.RECEIVE_CREATE_CUSTOM_STAGE_RESPONSE](state) {
state.isSavingCustomStage = false;
},
[types.REQUEST_TASKS_BY_TYPE_DATA](state) {},
[types.REQUEST_TASKS_BY_TYPE_DATA_ERROR](state) {},
[types.REQUEST_TASKS_BY_TYPE_DATA_SUCCESS](state) {},
[types.REQUEST_TASKS_BY_TYPE_DATA](state) {
// [
// {
// "label": {
// "id": 1,
// "title": "label 1",
// "color": "#428BCA",
// "text_color": "#FFFFFF"
// },
// "series": [
// [
// "2018-01-01",
// 23
// ],
// [
// "2018-01-02",
// 5
// ]
// ]
// },
// {
// "label": {
// "id": 2,
// "title": "label 3",
// "color": "#428BCA",
// "text_color": "#FFFFFF"
// },
// "series": [
// [
// "2018-01-01",
// 3
// ],
// [
// "2018-01-03",
// 10
// ]
// ]
// }
// ]
// transforms the raw data into a dictionary
/*
{
labelId: {
issues: [],
merge_requests: []
}
}
*/
},
[types.RECEIVE_TASKS_BY_TYPE_DATA_ERROR](state) {},
[types.RECEIVE_TASKS_BY_TYPE_DATA_SUCCESS](state) {},
};
import { TASKS_BY_TYPE_SUBJECT_ISSUE } from '../constants';
export default () => ({
endpoints: {
cycleAnalyticsData: null,
......@@ -29,4 +31,10 @@ export default () => ({
labels: [],
customStageFormEvents: [],
tasksByType: {
subject: TASKS_BY_TYPE_SUBJECT_ISSUE, // issues | merge_requests, defaults to issues
// list of selected labels for the tasks by type chart
labelIds: [],
data: []
},
});
......@@ -107,6 +107,8 @@ describe 'Analytics (JavaScript fixtures)', :sidekiq_inline do
describe Analytics::TasksByTypeController, type: :controller do
render_views
let(:label) { create(:group_label, group: group) }
before do
stub_licensed_features(type_of_work_analytics: true)
stub_feature_flags(Gitlab::Analytics::TASKS_BY_TYPE_CHART_FEATURE_FLAG => true)
......@@ -117,7 +119,7 @@ describe 'Analytics (JavaScript fixtures)', :sidekiq_inline do
end
it 'analytics/tasks_by_type.json' do
params = { group_id: group.full_path, label_ids: [1, 2], created_after: '2018-01-01', created_before: '2019-01-01' }
params = { group_id: group.full_path, label_ids: [label.id], created_after: 10.days.ago, subject: 'Issue' }
get(:show, params: params, format: :json)
......
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