Commit 8c113249 authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Fetch data for the filter bar tokens

Adds vuex actions to fetch and update
data for the VSA filter bar tokens

Adds additional action / mutation specs
parent 02793e19
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { __ } from '~/locale';
import Api from '~/api';
import * as types from './mutation_types';
const appendExtension = path => (path.indexOf('.') > -1 ? path : `${path}.json`);
export const setPaths = ({ commit }, { milestonesPath = '', labelsPath = '' }) => {
export const setPaths = ({ dispatch, commit }, { milestonesPath = '', labelsPath = '' }) => {
commit(types.SET_MILESTONES_PATH, appendExtension(milestonesPath));
commit(types.SET_LABELS_PATH, appendExtension(labelsPath));
return Promise.all([
dispatch('fetchLabels'),
dispatch('fetchMilestones'),
dispatch('fetchAuthors'),
dispatch('fetchAssignees'),
]);
};
export const fetchMilestones = ({ commit, state }) => {
commit(types.REQUEST_MILESTONES);
const { milestonesPath } = state;
return axios
.get(milestonesPath)
.then(({ data }) => commit(types.RECEIVE_MILESTONES_SUCCESS, data))
.catch(({ response }) => {
const { status } = response;
commit(types.RECEIVE_MILESTONES_ERROR, status);
createFlash(__('Failed to load milestones. Please try again.'));
});
};
export const fetchLabels = ({ commit, state }) => {
commit(types.REQUEST_LABELS);
return axios
.get(state.labelsPath)
.then(({ data }) => commit(types.RECEIVE_LABELS_SUCCESS, data))
.catch(({ response }) => {
const { status } = response;
commit(types.RECEIVE_LABELS_ERROR, status);
createFlash(__('Failed to load labels. Please try again.'));
});
};
const fetchUser = ({ commit, endpoint, query, action, errorMessage }) => {
commit(`REQUEST_${action}`);
return Api.groupMembers(endpoint, { query })
.then(({ data }) => commit(`RECEIVE_${action}_SUCCESS`, data))
.catch(({ response }) => {
const { status } = response;
commit(`RECEIVE_${action}_ERROR`, status);
createFlash(errorMessage);
});
};
export const fetchAuthors = ({ commit, rootGetters }, query = '') => {
const { currentGroupPath } = rootGetters;
return fetchUser({
commit,
query,
endpoint: currentGroupPath,
action: 'AUTHORS',
errorMessage: __('Failed to load authors. Please try again.'),
});
};
export const fetchAssignees = ({ commit, rootGetters }, query = '') => {
const { currentGroupPath } = rootGetters;
return fetchUser({
commit,
query,
endpoint: currentGroupPath,
action: 'ASSIGNEES',
errorMessage: __('Failed to load assignees. Please try again.'),
});
};
export const setFilters = ({ dispatch, state }, params) => {
......
export const SET_MILESTONES_PATH = 'SET_MILESTONES_PATH';
export const SET_LABELS_PATH = 'SET_LABELS_PATH';
export const REQUEST_MILESTONES = 'REQUEST_MILESTONES';
export const RECEIVE_MILESTONES_SUCCESS = 'RECEIVE_MILESTONES_SUCCESS';
export const RECEIVE_MILESTONES_ERROR = 'RECEIVE_MILESTONES_ERROR';
export const REQUEST_LABELS = 'REQUEST_LABELS';
export const RECEIVE_LABELS_SUCCESS = 'RECEIVE_LABELS_SUCCESS';
export const RECEIVE_LABELS_ERROR = 'RECEIVE_LABELS_ERROR';
export const REQUEST_AUTHORS = 'REQUEST_AUTHORS';
export const RECEIVE_AUTHORS_SUCCESS = 'RECEIVE_AUTHORS_SUCCESS';
export const RECEIVE_AUTHORS_ERROR = 'RECEIVE_AUTHORS_ERROR';
export const REQUEST_ASSIGNEES = 'REQUEST_ASSIGNEES';
export const RECEIVE_ASSIGNEES_SUCCESS = 'RECEIVE_ASSIGNEES_SUCCESS';
export const RECEIVE_ASSIGNEES_ERROR = 'RECEIVE_ASSIGNEES_ERROR';
......@@ -7,4 +7,48 @@ export default {
[types.SET_LABELS_PATH](state, labelsPath) {
state.labelsPath = labelsPath;
},
[types.REQUEST_MILESTONES](state) {
state.milestones.isLoading = true;
},
[types.RECEIVE_MILESTONES_SUCCESS](state, data) {
state.milestones.isLoading = false;
state.milestones.data = data;
},
[types.RECEIVE_MILESTONES_ERROR](state) {
state.milestones.isLoading = false;
state.milestones.data = [];
},
[types.REQUEST_LABELS](state) {
state.labels.isLoading = true;
},
[types.RECEIVE_LABELS_SUCCESS](state, data) {
state.labels.isLoading = false;
state.labels.data = data;
},
[types.RECEIVE_LABELS_ERROR](state) {
state.labels.isLoading = false;
state.labels.data = [];
},
[types.REQUEST_AUTHORS](state) {
state.authors.isLoading = true;
},
[types.RECEIVE_AUTHORS_SUCCESS](state, data) {
state.authors.isLoading = false;
state.authors.data = data;
},
[types.RECEIVE_AUTHORS_ERROR](state) {
state.authors.isLoading = false;
state.authors.data = [];
},
[types.REQUEST_ASSIGNEES](state) {
state.assignees.isLoading = true;
},
[types.RECEIVE_ASSIGNEES_SUCCESS](state, data) {
state.assignees.isLoading = false;
state.assignees.data = data;
},
[types.RECEIVE_ASSIGNEES_ERROR](state) {
state.assignees.isLoading = false;
state.assignees.data = [];
},
};
......@@ -30,12 +30,15 @@ export default {
return this.config.labels;
},
filteredLabels() {
return this.labels
.filter(label => label.title.toLowerCase().indexOf(this.value.data?.toLowerCase()) !== -1)
.map(label => ({
...label,
value: this.getEscapedText(label.title),
}));
const labelsList = this.labels.map(label => ({
...label,
value: this.getEscapedText(label.title),
}));
return this.value?.data
? labelsList.filter(
label => label.title.toLowerCase().indexOf(this.value.data?.toLowerCase()) !== -1,
)
: labelsList;
},
},
methods: {
......
......@@ -4,7 +4,8 @@ import testAction from 'helpers/vuex_action_helper';
import * as actions from 'ee/analytics/cycle_analytics/store/modules/filters/actions';
import * as types from 'ee/analytics/cycle_analytics/store/modules/filters/mutation_types';
import initialState from 'ee/analytics/cycle_analytics/store/modules/filters/state';
import { filterLabels } from '../../../mock_data';
import createFlash from '~/flash';
import { filterMilestones, filterUsers, filterLabels } from '../../../mock_data';
const milestonesPath = 'fake_milestones_path';
const labelsPath = 'fake_labels_path';
......@@ -77,8 +78,185 @@ describe('Filters actions', () => {
{ payload: 'fake_milestones_path.json', type: types.SET_MILESTONES_PATH },
{ payload: 'fake_labels_path.json', type: types.SET_LABELS_PATH },
],
[],
[
{ type: 'fetchLabels' },
{ type: 'fetchMilestones' },
{ type: 'fetchAuthors' },
{ type: 'fetchAssignees' },
],
);
});
});
describe('fetchAuthors', () => {
describe('success', () => {
beforeEach(() => {
mock.onAny().replyOnce(200, filterUsers);
});
it('dispatches RECEIVE_AUTHORS_SUCCESS with received data', () => {
testAction(
actions.fetchAuthors,
null,
state,
[
{ type: types.REQUEST_AUTHORS },
{ type: types.RECEIVE_AUTHORS_SUCCESS, payload: filterUsers },
],
[],
);
});
});
describe('error', () => {
beforeEach(() => {
mock.onAny().replyOnce(500);
});
it('dispatches RECEIVE_AUTHORS_ERROR', () => {
return testAction(
actions.fetchAuthors,
null,
state,
[
{ type: types.REQUEST_AUTHORS },
{
type: types.RECEIVE_AUTHORS_ERROR,
payload: 500,
},
],
[],
).then(() => expect(createFlash).toHaveBeenCalled());
});
});
});
describe('fetchMilestones', () => {
describe('success', () => {
beforeEach(() => {
mock.onGet(milestonesPath).replyOnce(200, filterMilestones);
});
it('dispatches RECEIVE_MILESTONES_SUCCESS with received data', () => {
testAction(
actions.fetchMilestones,
null,
{ ...state, milestonesPath },
[
{ type: types.REQUEST_MILESTONES },
{ type: types.RECEIVE_MILESTONES_SUCCESS, payload: filterMilestones },
],
[],
);
});
});
describe('error', () => {
beforeEach(() => {
mock.onAny().replyOnce(500);
});
it('dispatches RECEIVE_MILESTONES_ERROR', () => {
return testAction(
actions.fetchMilestones,
null,
state,
[
{ type: types.REQUEST_MILESTONES },
{
type: types.RECEIVE_MILESTONES_ERROR,
payload: 500,
},
],
[],
).then(() => expect(createFlash).toHaveBeenCalled());
});
});
});
describe('fetchAssignees', () => {
describe('success', () => {
beforeEach(() => {
mock.onAny().replyOnce(200, filterUsers);
});
it('dispatches RECEIVE_ASSIGNEES_SUCCESS with received data', () => {
testAction(
actions.fetchAssignees,
null,
{ ...state, milestonesPath },
[
{ type: types.REQUEST_ASSIGNEES },
{ type: types.RECEIVE_ASSIGNEES_SUCCESS, payload: filterUsers },
],
[],
);
});
});
describe('error', () => {
beforeEach(() => {
mock.onAny().replyOnce(500);
});
it('dispatches RECEIVE_ASSIGNEES_ERROR', () => {
return testAction(
actions.fetchAssignees,
null,
state,
[
{ type: types.REQUEST_ASSIGNEES },
{
type: types.RECEIVE_ASSIGNEES_ERROR,
payload: 500,
},
],
[],
).then(() => expect(createFlash).toHaveBeenCalled());
});
});
});
describe('fetchLabels', () => {
describe('success', () => {
beforeEach(() => {
mock.onGet(labelsPath).replyOnce(200, filterLabels);
});
it('dispatches RECEIVE_LABELS_SUCCESS with received data', () => {
testAction(
actions.fetchLabels,
null,
{ ...state, labelsPath },
[
{ type: types.REQUEST_LABELS },
{ type: types.RECEIVE_LABELS_SUCCESS, payload: filterLabels },
],
[],
);
});
});
describe('error', () => {
beforeEach(() => {
mock.onAny().replyOnce(500);
});
it('dispatches RECEIVE_LABELS_ERROR', () => {
return testAction(
actions.fetchLabels,
null,
state,
[
{ type: types.REQUEST_LABELS },
{
type: types.RECEIVE_LABELS_ERROR,
payload: 500,
},
],
[],
).then(() => expect(createFlash).toHaveBeenCalled());
});
});
});
});
import mutations from 'ee/analytics/cycle_analytics/store/modules/filters/mutations';
import * as types from 'ee/analytics/cycle_analytics/store/modules/filters/mutation_types';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { filterMilestones, filterUsers, filterLabels } from '../../../mock_data';
let state = null;
const milestones = filterMilestones.map(convertObjectPropsToCamelCase);
const users = filterUsers.map(convertObjectPropsToCamelCase);
const labels = filterLabels.map(convertObjectPropsToCamelCase);
describe('Filters mutations', () => {
beforeEach(() => {
state = { initialTokens: {}, milestones: {}, authors: {}, labels: {}, assignees: {} };
......
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