Commit 05e3a857 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'mw-cr-mvc-search-store' into 'master'

Code Review Analytics: Add Vuex store to app

See merge request gitlab-org/gitlab!22964
parents be5cd8b9 694a1b17
import Vue from 'vue'; import Vue from 'vue';
import createStore from './store';
import CodeAnalyticsApp from './components/app.vue'; import CodeAnalyticsApp from './components/app.vue';
import FilteredSearchCodeReviewAnalytics from './filtered_search_code_review_analytics'; import FilteredSearchCodeReviewAnalytics from './filtered_search_code_review_analytics';
export default () => { export default () => {
const container = document.getElementById('js-code-review-analytics'); const container = document.getElementById('js-code-review-analytics');
const { projectId } = container.dataset;
if (!container) return; if (!container) return;
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
new Vue({ new Vue({
el: container, el: container,
mounted() { store: createStore(),
created() {
this.filterManager = new FilteredSearchCodeReviewAnalytics(); this.filterManager = new FilteredSearchCodeReviewAnalytics();
this.filterManager.setup(); this.filterManager.setup();
}, },
render(h) { render(h) {
return h(CodeAnalyticsApp, {}); return h(CodeAnalyticsApp, {
props: {
projectId: Number(projectId),
},
});
}, },
}); });
}; };
<script> <script>
export default {}; import { mapActions } from 'vuex';
export default {
props: {
projectId: {
type: Number,
required: true,
},
},
created() {
this.setProjectId(this.projectId);
},
methods: {
...mapActions(['setProjectId']),
},
};
</script> </script>
<template> <template>
<div class="mt-2"></div> <div class="mt-2">
<div>
<span class="font-weight-bold">{{ __('Merge Requests in Review') }}</span>
</div>
</div>
</template> </template>
import CodeReviewAnalyticsFilteredSearchTokenKeys from './code_review_analytics_filtered_search_token_keys'; import CodeReviewAnalyticsFilteredSearchTokenKeys from './code_review_analytics_filtered_search_token_keys';
import FilteredSearchManager from '~/filtered_search/filtered_search_manager'; 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 { export default class FilteredSearchCodeReviewAnalytics extends FilteredSearchManager {
constructor() { constructor() {
...@@ -13,4 +15,13 @@ export default class FilteredSearchCodeReviewAnalytics extends FilteredSearchMan ...@@ -13,4 +15,13 @@ export default class FilteredSearchCodeReviewAnalytics extends FilteredSearchMan
this.isHandledAsync = true; 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', () => { document.addEventListener('DOMContentLoaded', () => {
initCodeReviewAnalyticsApp(); initCodeReviewAnalyticsApp();
......
...@@ -6,4 +6,4 @@ ...@@ -6,4 +6,4 @@
= _('Code Review') = _('Code Review')
%span.text-secondary= _('Review time is defined as the time it takes from first comment until merged.') %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 = 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);
});
});
});
...@@ -11370,6 +11370,9 @@ msgstr "" ...@@ -11370,6 +11370,9 @@ msgstr ""
msgid "Merge Requests created" msgid "Merge Requests created"
msgstr "" msgstr ""
msgid "Merge Requests in Review"
msgstr ""
msgid "Merge commit message" msgid "Merge commit message"
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