Commit 694a1b17 authored by Martin Wortschack's avatar Martin Wortschack

Add Vuex store to app

- Updates the store with the
filters set in the search bar
parent 93f05ed3
import Vue from 'vue';
import createStore from './store';
import CodeAnalyticsApp from './components/app.vue';
import FilteredSearchCodeReviewAnalytics from './filtered_search_code_review_analytics';
export default () => {
const container = document.getElementById('js-code-review-analytics');
const { projectId } = container.dataset;
if (!container) return;
// eslint-disable-next-line no-new
new Vue({
el: container,
mounted() {
store: createStore(),
created() {
this.filterManager = new FilteredSearchCodeReviewAnalytics();
this.filterManager.setup();
},
render(h) {
return h(CodeAnalyticsApp, {});
return h(CodeAnalyticsApp, {
props: {
projectId: Number(projectId),
},
});
},
});
};
<script>
export default {};
import { mapActions } from 'vuex';
export default {
props: {
projectId: {
type: Number,
required: true,
},
},
created() {
this.setProjectId(this.projectId);
},
methods: {
...mapActions(['setProjectId']),
},
};
</script>
<template>
<div class="mt-2"></div>
<div class="mt-2">
<div>
<span class="font-weight-bold">{{ __('Merge Requests in Review') }}</span>
</div>
</div>
</template>
import CodeReviewAnalyticsFilteredSearchTokenKeys from './code_review_analytics_filtered_search_token_keys';
import FilteredSearchManager from '~/filtered_search/filtered_search_manager';
import { urlParamsToObject } from '~/lib/utils/common_utils';
import createStore from './store';
export default class FilteredSearchCodeReviewAnalytics extends FilteredSearchManager {
constructor() {
......@@ -13,4 +15,13 @@ export default class FilteredSearchCodeReviewAnalytics extends FilteredSearchMan
this.isHandledAsync = true;
}
/**
* Updates filters in code review analytics store
*/
updateObject = path => {
const filters = urlParamsToObject(path);
const store = createStore();
store.dispatch('setFilters', filters);
};
}
import * as types from './mutation_types';
export const setProjectId = ({ commit }, projectId) => commit(types.SET_PROJECT_ID, projectId);
export const setFilters = ({ commit }, { label_name, milestone_title }) => {
commit(types.SET_FILTERS, { labelName: label_name, milestoneTitle: milestone_title });
};
import Vue from 'vue';
import Vuex from 'vuex';
import * as actions from './actions';
import mutations from './mutations';
import state from './state';
Vue.use(Vuex);
const createStore = () =>
new Vuex.Store({
state: state(),
actions,
mutations,
});
export default createStore;
export const SET_PROJECT_ID = 'SET_PROJECT_ID';
export const SET_FILTERS = 'SET_FILTERS';
import * as types from './mutation_types';
export default {
[types.SET_PROJECT_ID](state, projectId) {
state.projectId = projectId;
},
[types.SET_FILTERS](state, { labelName, milestoneTitle }) {
state.filters.labelName = labelName;
state.filters.milestoneTitle = milestoneTitle;
},
};
export default () => ({
projectId: null,
filters: {
labelName: [],
milestoneTitle: null,
},
});
import initCodeReviewAnalyticsApp from 'ee/analytics/code_review_analytics';
import initCodeReviewAnalyticsApp from 'ee/analytics/code_review_analytics/code_review_analytics_bundle';
document.addEventListener('DOMContentLoaded', () => {
initCodeReviewAnalyticsApp();
......
......@@ -6,4 +6,4 @@
= _('Code Review')
%span.text-secondary= _('Review time is defined as the time it takes from first comment until merged.')
= render 'shared/issuable/search_bar', type: :issues_analytics, show_sorting_dropdown: false
#js-code-review-analytics{ data: { project: @project } }
#js-code-review-analytics{ data: { project_id: @project.id } }
import testAction from 'helpers/vuex_action_helper';
import * as actions from 'ee/analytics/code_review_analytics/store/actions';
import * as types from 'ee/analytics/code_review_analytics/store/mutation_types';
import getInitialState from 'ee/analytics/code_review_analytics/store/state';
import createFlash from '~/flash';
jest.mock('~/flash', () => jest.fn());
describe('Code review analytics actions', () => {
afterEach(() => {
createFlash.mockClear();
});
describe('setProjectId', () => {
it('commits the SET_PROJECT_ID mutation', () =>
testAction(
actions.setProjectId,
1,
getInitialState(),
[
{
type: types.SET_PROJECT_ID,
payload: 1,
},
],
[],
));
});
describe('setFilters', () => {
const milestoneTitle = 'my milestone';
const labelName = ['first label', 'second label'];
it('commits the SET_FILTERS mutation', () => {
testAction(
actions.setFilters,
{ milestone_title: milestoneTitle, label_name: labelName },
getInitialState(),
[
{
type: types.SET_FILTERS,
payload: { milestoneTitle, labelName },
},
],
[],
);
});
});
});
import * as types from 'ee/analytics/code_review_analytics/store/mutation_types';
import mutations from 'ee/analytics/code_review_analytics/store/mutations';
import getInitialState from 'ee/analytics/code_review_analytics/store/state';
describe('Code review analytics mutations', () => {
let state;
const milestoneTitle = 'my milestone';
const labelName = ['first label', 'second label'];
beforeEach(() => {
state = getInitialState();
});
describe(types.SET_PROJECT_ID, () => {
it('sets the project id', () => {
mutations[types.SET_PROJECT_ID](state, 1);
expect(state.projectId).toBe(1);
});
});
describe(types.SET_FILTERS, () => {
it('updates milestoneTitle and labelName', () => {
mutations[types.SET_FILTERS](state, { milestoneTitle, labelName });
expect(state.filters.milestoneTitle).toBe(milestoneTitle);
expect(state.filters.labelName).toBe(labelName);
});
});
});
......@@ -11346,6 +11346,9 @@ msgstr ""
msgid "Merge Requests created"
msgstr ""
msgid "Merge Requests in Review"
msgstr ""
msgid "Merge commit message"
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