Commit 03820e9b authored by Phil Hughes's avatar Phil Hughes

fetch both created & assigned

show badges for both

[ci skip]
parent 0b278a93
...@@ -38,6 +38,7 @@ export default { ...@@ -38,6 +38,7 @@ export default {
data() { data() {
return { return {
showTooltip: false, showTooltip: false,
showMergeRequestsDropdown: false,
}; };
}, },
computed: { computed: {
...@@ -67,6 +68,23 @@ export default { ...@@ -67,6 +68,23 @@ export default {
this.showTooltip = this.$refs.branchId.scrollWidth > this.$refs.branchId.offsetWidth; this.showTooltip = this.$refs.branchId.scrollWidth > this.$refs.branchId.offsetWidth;
}); });
}, },
showMergeRequestsDropdown() {
if (this.showMergeRequestsDropdown) {
document.addEventListener('click', this.hideMergeRequestDropdown);
} else {
document.removeEventListener('click', this.hideMergeRequestDropdown);
}
},
},
methods: {
hideMergeRequestDropdown(e) {
if (this.$refs.mergeRequestDropdown.contains(e.target)) return;
this.showMergeRequestsDropdown = false;
},
toggleMergeRequestDropdown() {
this.showMergeRequestsDropdown = !this.showMergeRequestsDropdown;
},
}, },
}; };
</script> </script>
...@@ -91,12 +109,17 @@ export default { ...@@ -91,12 +109,17 @@ export default {
</div> </div>
</template> </template>
<template v-else> <template v-else>
<div class="context-header ide-context-header dropdown"> <div
class="context-header ide-context-header dropdown"
:class="{
show: showMergeRequestsDropdown
}"
ref="mergeRequestDropdown"
>
<a <a
href="#" href="#"
role="button" role="button"
@click.prevent @click.prevent="toggleMergeRequestDropdown"
data-toggle="dropdown"
> >
<div <div
v-if="currentProject.avatar_url" v-if="currentProject.avatar_url"
...@@ -148,7 +171,10 @@ export default { ...@@ -148,7 +171,10 @@ export default {
name="chevron-down" name="chevron-down"
/> />
</a> </a>
<merge-request-dropdown /> <merge-request-dropdown
v-if="showMergeRequestsDropdown"
@hide="toggleMergeRequestDropdown"
/>
</div> </div>
<div class="multi-file-commit-panel-inner-scroll"> <div class="multi-file-commit-panel-inner-scroll">
<component <component
......
<script> <script>
import { mapActions, mapState } from 'vuex'; import { mapGetters, mapState } from 'vuex';
import Tabs from '../../../vue_shared/components/tabs/tabs'; import Tabs from '../../../vue_shared/components/tabs/tabs';
import Tab from '../../../vue_shared/components/tabs/tab.vue'; import Tab from '../../../vue_shared/components/tabs/tab.vue';
import List from './list.vue'; import List from './list.vue';
import { scopes } from '../../stores/modules/merge_requests/constants';
export default { export default {
components: { components: {
...@@ -11,28 +10,16 @@ export default { ...@@ -11,28 +10,16 @@ export default {
Tab, Tab,
List, List,
}, },
data() {
return {
activeTabIndex: 0,
};
},
computed: { computed: {
...mapState('mergeRequests', ['isLoading', 'mergeRequests']), ...mapGetters('mergeRequests', ['assignedData', 'createdData']),
...mapState(['currentMergeRequestId']), ...mapState(['currentMergeRequestId']),
tabScope() { createdMergeRequestLength() {
return this.activeTabIndex === 0 ? scopes.createdByMe : scopes.assignedToMe; return this.createdData.mergeRequests.length;
},
}, },
mounted() {
this.fetchMergeRequests();
}, },
methods: { methods: {
...mapActions('mergeRequests', ['fetchMergeRequests', 'setScope']), hideDropdown() {
updateActiveTab(index) { this.$emit('hide');
this.activeTabIndex = index;
this.setScope(this.tabScope);
this.fetchMergeRequests();
}, },
}, },
}; };
...@@ -40,31 +27,33 @@ export default { ...@@ -40,31 +27,33 @@ export default {
<template> <template>
<div class="dropdown-menu ide-merge-requests-dropdown"> <div class="dropdown-menu ide-merge-requests-dropdown">
<tabs <tabs stop-propagation>
stop-propagation <tab active>
@changed="updateActiveTab" <template slot="title">
> {{ __('Created by me') }}
<tab <span class="badge badge-pill">
:title="__('Created by me')" {{ createdMergeRequestLength }}
active </span>
> </template>
<list <list
v-if="activeTabIndex === 0" type="created"
:is-loading="isLoading"
:items="mergeRequests"
:current-id="currentMergeRequestId" :current-id="currentMergeRequestId"
:empty-text="__('You have not created any merge requests')" :empty-text="__('You have not created any merge requests')"
@search="fetchMergeRequests" @hide="hideDropdown"
/> />
</tab> </tab>
<tab :title="__('Assigned to me')"> <tab>
<template slot="title">
{{ __('Assigned to me') }}
<span class="badge badge-pill">
{{ assignedData.mergeRequests.length }}
</span>
</template>
<list <list
v-if="activeTabIndex === 1" type="assigned"
:is-loading="isLoading"
:items="mergeRequests"
:current-id="currentMergeRequestId" :current-id="currentMergeRequestId"
:empty-text="__('You do not have any assigned merge requests')" :empty-text="__('You do not have any assigned merge requests')"
@search="fetchMergeRequests" @hide="hideDropdown"
/> />
</tab> </tab>
</tabs> </tabs>
......
<script> <script>
import { mapActions, mapGetters } from 'vuex';
import _ from 'underscore'; import _ from 'underscore';
import LoadingIcon from '../../../vue_shared/components/loading_icon.vue'; import LoadingIcon from '../../../vue_shared/components/loading_icon.vue';
import Item from './item.vue'; import Item from './item.vue';
...@@ -9,12 +10,8 @@ export default { ...@@ -9,12 +10,8 @@ export default {
Item, Item,
}, },
props: { props: {
isLoading: { type: {
type: Boolean, type: String,
required: true,
},
items: {
type: Array,
required: true, required: true,
}, },
currentId: { currentId: {
...@@ -32,24 +29,41 @@ export default { ...@@ -32,24 +29,41 @@ export default {
}; };
}, },
computed: { computed: {
...mapGetters('mergeRequests', ['getData']),
data() {
return this.getData(this.type);
},
isLoading() {
return this.data.isLoading;
},
mergeRequests() {
return this.data.mergeRequests;
},
hasMergeRequests() { hasMergeRequests() {
return this.items.length !== 0; return this.mergeRequests.length !== 0;
}, },
hasNoSearchResults() { hasNoSearchResults() {
return this.search !== '' && !this.hasMergeRequests; return this.search !== '' && !this.hasMergeRequests;
}, },
}, },
watch: { mounted() {
isLoading() { this.loadMergeRequests();
this.focusSearch();
},
}, },
methods: { methods: {
...mapActions('mergeRequests', ['fetchMergeRequests']),
...mapActions(['closeAllFiles']),
loadMergeRequests() {
this.fetchMergeRequests({ type: this.type, search: this.search });
},
viewMergeRequest(item) { viewMergeRequest(item) {
return this.closeAllFiles()
.then(() => {
this.$emit('hide');
this.$router.push(`/project/${item.projectPathWithNamespace}/merge_requests/${item.iid}`); this.$router.push(`/project/${item.projectPathWithNamespace}/merge_requests/${item.iid}`);
});
}, },
searchMergeRequests: _.debounce(function debounceSearch() { searchMergeRequests: _.debounce(function debounceSearch() {
this.$emit('search', this.search); this.loadMergeRequests();
}, 250), }, 250),
focusSearch() { focusSearch() {
if (!this.isLoading) { if (!this.isLoading) {
...@@ -88,7 +102,7 @@ export default { ...@@ -88,7 +102,7 @@ export default {
<ul class="mb-3"> <ul class="mb-3">
<template v-if="hasMergeRequests"> <template v-if="hasMergeRequests">
<li <li
v-for="item in items" v-for="item in mergeRequests"
:key="item.id" :key="item.id"
> >
<item <item
...@@ -103,7 +117,7 @@ export default { ...@@ -103,7 +117,7 @@ export default {
class="ide-merge-requests-empty d-flex align-items-center justify-content-center" class="ide-merge-requests-empty d-flex align-items-center justify-content-center"
> >
<template v-if="hasNoSearchResults"> <template v-if="hasNoSearchResults">
No merge requests found {{ __('No merge requests found') }}
</template> </template>
<template v-else> <template v-else>
{{ emptyText }} {{ emptyText }}
......
...@@ -17,9 +17,7 @@ export const getMergeRequestData = ( ...@@ -17,9 +17,7 @@ export const getMergeRequestData = (
mergeRequestId, mergeRequestId,
mergeRequest: data, mergeRequest: data,
}); });
if (!state.currentMergeRequestId) {
commit(types.SET_CURRENT_MERGE_REQUEST, mergeRequestId); commit(types.SET_CURRENT_MERGE_REQUEST, mergeRequestId);
}
resolve(data); resolve(data);
}) })
.catch(() => { .catch(() => {
......
import { __ } from '../../../../locale'; import { __ } from '../../../../locale';
import Api from '../../../../api'; import Api from '../../../../api';
import flash from '../../../../flash'; import flash from '../../../../flash';
import { scopes } from './constants';
import * as types from './mutation_types'; import * as types from './mutation_types';
export const requestMergeRequests = ({ commit }) => commit(types.REQUEST_MERGE_REQUESTS); export const requestMergeRequests = ({ commit }, type) =>
export const receiveMergeRequestsError = ({ commit }) => { commit(types.REQUEST_MERGE_REQUESTS, type);
export const receiveMergeRequestsError = ({ commit }, type) => {
flash(__('Error loading merge requests.')); flash(__('Error loading merge requests.'));
commit(types.RECEIVE_MERGE_REQUESTS_ERROR); commit(types.RECEIVE_MERGE_REQUESTS_ERROR, type);
}; };
export const receiveMergeRequestsSuccess = ({ commit }, data) => export const receiveMergeRequestsSuccess = ({ commit }, { type, data }) =>
commit(types.RECEIVE_MERGE_REQUESTS_SUCCESS, data); commit(types.RECEIVE_MERGE_REQUESTS_SUCCESS, { type, data });
export const fetchMergeRequests = ({ dispatch, state: { scope, state } }, search = '') => { export const fetchMergeRequests = ({ dispatch, state: { state } }, { type, search = '' }) => {
dispatch('requestMergeRequests'); const scope = scopes[type];
dispatch('resetMergeRequests'); dispatch('requestMergeRequests', type);
dispatch('resetMergeRequests', type);
Api.mergeRequests({ scope, state, search }) Api.mergeRequests({ scope, state, search })
.then(({ data }) => dispatch('receiveMergeRequestsSuccess', data)) .then(({ data }) => dispatch('receiveMergeRequestsSuccess', { type, data }))
.catch(() => dispatch('receiveMergeRequestsError')); .catch(() => dispatch('receiveMergeRequestsError', type));
}; };
export const resetMergeRequests = ({ commit }) => commit(types.RESET_MERGE_REQUESTS); export const resetMergeRequests = ({ commit }, type) => commit(types.RESET_MERGE_REQUESTS, type);
export const setScope = ({ commit }, scope) => commit(types.SET_SCOPE, scope);
export default () => {}; export default () => {};
export const scopes = { export const scopes = {
assignedToMe: 'assigned-to-me', assigned: 'assigned-to-me',
createdByMe: 'created-by-me', created: 'created-by-me',
}; };
export const states = { export const states = {
......
export const getData = state => type => state[type];
export const assignedData = state => state.assigned;
export const createdData = state => state.created;
import state from './state'; import state from './state';
import * as actions from './actions'; import * as actions from './actions';
import * as getters from './getters';
import mutations from './mutations'; import mutations from './mutations';
export default { export default {
...@@ -7,4 +8,5 @@ export default { ...@@ -7,4 +8,5 @@ export default {
state: state(), state: state(),
actions, actions,
mutations, mutations,
getters,
}; };
...@@ -3,5 +3,3 @@ export const RECEIVE_MERGE_REQUESTS_ERROR = 'RECEIVE_MERGE_REQUESTS_ERROR'; ...@@ -3,5 +3,3 @@ export const RECEIVE_MERGE_REQUESTS_ERROR = 'RECEIVE_MERGE_REQUESTS_ERROR';
export const RECEIVE_MERGE_REQUESTS_SUCCESS = 'RECEIVE_MERGE_REQUESTS_SUCCESS'; export const RECEIVE_MERGE_REQUESTS_SUCCESS = 'RECEIVE_MERGE_REQUESTS_SUCCESS';
export const RESET_MERGE_REQUESTS = 'RESET_MERGE_REQUESTS'; export const RESET_MERGE_REQUESTS = 'RESET_MERGE_REQUESTS';
export const SET_SCOPE = 'SET_SCOPE';
...@@ -2,15 +2,15 @@ ...@@ -2,15 +2,15 @@
import * as types from './mutation_types'; import * as types from './mutation_types';
export default { export default {
[types.REQUEST_MERGE_REQUESTS](state) { [types.REQUEST_MERGE_REQUESTS](state, type) {
state.isLoading = true; state[type].isLoading = true;
}, },
[types.RECEIVE_MERGE_REQUESTS_ERROR](state) { [types.RECEIVE_MERGE_REQUESTS_ERROR](state, type) {
state.isLoading = false; state[type].isLoading = false;
}, },
[types.RECEIVE_MERGE_REQUESTS_SUCCESS](state, data) { [types.RECEIVE_MERGE_REQUESTS_SUCCESS](state, { type, data }) {
state.isLoading = false; state[type].isLoading = false;
state.mergeRequests = data.map(mergeRequest => ({ state[type].mergeRequests = data.map(mergeRequest => ({
id: mergeRequest.id, id: mergeRequest.id,
iid: mergeRequest.iid, iid: mergeRequest.iid,
title: mergeRequest.title, title: mergeRequest.title,
...@@ -20,10 +20,7 @@ export default { ...@@ -20,10 +20,7 @@ export default {
.replace(`/merge_requests/${mergeRequest.iid}`, ''), .replace(`/merge_requests/${mergeRequest.iid}`, ''),
})); }));
}, },
[types.RESET_MERGE_REQUESTS](state) { [types.RESET_MERGE_REQUESTS](state, type) {
state.mergeRequests = []; state[type].mergeRequests = [];
},
[types.SET_SCOPE](state, scope) {
state.scope = scope;
}, },
}; };
import { scopes, states } from './constants'; import { states } from './constants';
export default () => ({ export default () => ({
created: {
isLoading: false, isLoading: false,
mergeRequests: [], mergeRequests: [],
scope: scopes.createdByMe, },
assigned: {
isLoading: false,
mergeRequests: [],
},
state: states.opened, state: states.opened,
}); });
...@@ -26,6 +26,9 @@ export default { ...@@ -26,6 +26,9 @@ export default {
created() { created() {
this.isTab = true; this.isTab = true;
}, },
updated() {
this.$parent.$forceUpdate();
},
}; };
</script> </script>
......
...@@ -29,8 +29,6 @@ export default { ...@@ -29,8 +29,6 @@ export default {
this.tabs[index].localActive = true; this.tabs[index].localActive = true;
this.currentIndex = index; this.currentIndex = index;
this.$emit('changed', this.currentIndex);
}, },
}, },
render(h) { render(h) {
......
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