diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-11-11 00:08:51 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-11-11 00:08:51 +0300 |
commit | 13bcb8221306526671a61df589f7c05505c9934c (patch) | |
tree | baa61780ec5f526ea180c209af8f4d75a5cb4425 /app/assets/javascripts/milestones | |
parent | 206b03aeae3a368983ac3d6ad5e5828030bbaacd (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/milestones')
6 files changed, 125 insertions, 10 deletions
diff --git a/app/assets/javascripts/milestones/components/milestone_combobox.vue b/app/assets/javascripts/milestones/components/milestone_combobox.vue index fad61b95124..08fd5a5994f 100644 --- a/app/assets/javascripts/milestones/components/milestone_combobox.vue +++ b/app/assets/javascripts/milestones/components/milestone_combobox.vue @@ -39,6 +39,16 @@ export default { type: String, required: true, }, + groupId: { + type: String, + required: false, + default: '', + }, + groupMilestonesAvailable: { + type: Boolean, + required: false, + default: false, + }, extraLinks: { type: Array, default: () => [], @@ -56,12 +66,13 @@ export default { noMilestone: s__('MilestoneCombobox|No milestone'), noResultsLabel: s__('MilestoneCombobox|No matching results'), searchMilestones: s__('MilestoneCombobox|Search Milestones'), - searhErrorMessage: s__('MilestoneCombobox|An error occurred while searching for milestones'), + searchErrorMessage: s__('MilestoneCombobox|An error occurred while searching for milestones'), projectMilestones: s__('MilestoneCombobox|Project milestones'), + groupMilestones: s__('MilestoneCombobox|Group milestones'), }, computed: { ...mapState(['matches', 'selectedMilestones']), - ...mapGetters(['isLoading']), + ...mapGetters(['isLoading', 'groupMilestonesEnabled']), selectedMilestonesLabel() { const { selectedMilestones } = this; const firstMilestoneName = selectedMilestones[0]; @@ -85,8 +96,14 @@ export default { this.matches.projectMilestones.totalCount > 0 || this.matches.projectMilestones.error, ); }, + showGroupMilestoneSection() { + return ( + this.groupMilestonesEnabled && + Boolean(this.matches.groupMilestones.totalCount > 0 || this.matches.groupMilestones.error) + ); + }, showNoResults() { - return !this.showProjectMilestoneSection; + return !this.showProjectMilestoneSection && !this.showGroupMilestoneSection; }, }, watch: { @@ -115,11 +132,15 @@ export default { }, SEARCH_DEBOUNCE_MS); this.setProjectId(this.projectId); + this.setGroupId(this.groupId); + this.setGroupMilestonesAvailable(this.groupMilestonesAvailable); this.fetchMilestones(); }, methods: { ...mapActions([ 'setProjectId', + 'setGroupId', + 'setGroupMilestonesAvailable', 'setSelectedMilestones', 'clearSelectedMilestones', 'toggleMilestones', @@ -194,15 +215,28 @@ export default { </template> <template v-else> <milestone-results-section + v-if="showProjectMilestoneSection" :section-title="$options.translations.projectMilestones" :total-count="matches.projectMilestones.totalCount" :items="matches.projectMilestones.list" :selected-milestones="selectedMilestones" :error="matches.projectMilestones.error" - :error-message="$options.translations.searhErrorMessage" + :error-message="$options.translations.searchErrorMessage" data-testid="project-milestones-section" @selected="selectMilestone($event)" /> + + <milestone-results-section + v-if="showGroupMilestoneSection" + :section-title="$options.translations.groupMilestones" + :total-count="matches.groupMilestones.totalCount" + :items="matches.groupMilestones.list" + :selected-milestones="selectedMilestones" + :error="matches.groupMilestones.error" + :error-message="$options.translations.searchErrorMessage" + data-testid="group-milestones-section" + @selected="selectMilestone($event)" + /> </template> <gl-dropdown-item v-for="(item, idx) in extraLinks" diff --git a/app/assets/javascripts/milestones/stores/actions.js b/app/assets/javascripts/milestones/stores/actions.js index 56a07562f62..df45c7156ad 100644 --- a/app/assets/javascripts/milestones/stores/actions.js +++ b/app/assets/javascripts/milestones/stores/actions.js @@ -2,6 +2,9 @@ import Api from '~/api'; import * as types from './mutation_types'; export const setProjectId = ({ commit }, projectId) => commit(types.SET_PROJECT_ID, projectId); +export const setGroupId = ({ commit }, groupId) => commit(types.SET_GROUP_ID, groupId); +export const setGroupMilestonesAvailable = ({ commit }, groupMilestonesAvailable) => + commit(types.SET_GROUP_MILESTONES_AVAILABLE, groupMilestonesAvailable); export const setSelectedMilestones = ({ commit }, selectedMilestones) => commit(types.SET_SELECTED_MILESTONES, selectedMilestones); @@ -18,13 +21,23 @@ export const toggleMilestones = ({ commit, state }, selectedMilestone) => { } }; -export const search = ({ dispatch, commit }, searchQuery) => { +export const search = ({ dispatch, commit, getters }, searchQuery) => { commit(types.SET_SEARCH_QUERY, searchQuery); - dispatch('searchMilestones'); + dispatch('searchProjectMilestones'); + if (getters.groupMilestonesEnabled) { + dispatch('searchGroupMilestones'); + } +}; + +export const fetchMilestones = ({ dispatch, getters }) => { + dispatch('fetchProjectMilestones'); + if (getters.groupMilestonesEnabled) { + dispatch('fetchGroupMilestones'); + } }; -export const fetchMilestones = ({ commit, state }) => { +export const fetchProjectMilestones = ({ commit, state }) => { commit(types.REQUEST_START); Api.projectMilestones(state.projectId) @@ -39,14 +52,29 @@ export const fetchMilestones = ({ commit, state }) => { }); }; -export const searchMilestones = ({ commit, state }) => { +export const fetchGroupMilestones = ({ commit, state }) => { commit(types.REQUEST_START); + Api.groupMilestones(state.groupId) + .then(response => { + commit(types.RECEIVE_GROUP_MILESTONES_SUCCESS, response); + }) + .catch(error => { + commit(types.RECEIVE_GROUP_MILESTONES_ERROR, error); + }) + .finally(() => { + commit(types.REQUEST_FINISH); + }); +}; + +export const searchProjectMilestones = ({ commit, state }) => { const options = { search: state.searchQuery, scope: 'milestones', }; + commit(types.REQUEST_START); + Api.projectSearch(state.projectId, options) .then(response => { commit(types.RECEIVE_PROJECT_MILESTONES_SUCCESS, response); @@ -58,3 +86,22 @@ export const searchMilestones = ({ commit, state }) => { commit(types.REQUEST_FINISH); }); }; + +export const searchGroupMilestones = ({ commit, state }) => { + const options = { + search: state.searchQuery, + }; + + commit(types.REQUEST_START); + + Api.groupMilestones(state.groupId, options) + .then(response => { + commit(types.RECEIVE_GROUP_MILESTONES_SUCCESS, response); + }) + .catch(error => { + commit(types.RECEIVE_GROUP_MILESTONES_ERROR, error); + }) + .finally(() => { + commit(types.REQUEST_FINISH); + }); +}; diff --git a/app/assets/javascripts/milestones/stores/getters.js b/app/assets/javascripts/milestones/stores/getters.js index d8a283403ec..b5fcfbe35d5 100644 --- a/app/assets/javascripts/milestones/stores/getters.js +++ b/app/assets/javascripts/milestones/stores/getters.js @@ -1,2 +1,6 @@ /** Returns `true` if there is at least one in-progress request */ export const isLoading = ({ requestCount }) => requestCount > 0; + +/** Returns `true` if there is a group ID and group milestones are available */ +export const groupMilestonesEnabled = ({ groupId, groupMilestonesAvailable }) => + Boolean(groupId && groupMilestonesAvailable); diff --git a/app/assets/javascripts/milestones/stores/mutation_types.js b/app/assets/javascripts/milestones/stores/mutation_types.js index 6c58fca9dca..22e50571e34 100644 --- a/app/assets/javascripts/milestones/stores/mutation_types.js +++ b/app/assets/javascripts/milestones/stores/mutation_types.js @@ -1,4 +1,6 @@ export const SET_PROJECT_ID = 'SET_PROJECT_ID'; +export const SET_GROUP_ID = 'SET_GROUP_ID'; +export const SET_GROUP_MILESTONES_AVAILABLE = 'SET_GROUP_MILESTONES_AVAILABLE'; export const SET_SELECTED_MILESTONES = 'SET_SELECTED_MILESTONES'; export const CLEAR_SELECTED_MILESTONES = 'CLEAR_SELECTED_MILESTONES'; @@ -12,3 +14,6 @@ export const REQUEST_FINISH = 'REQUEST_FINISH'; export const RECEIVE_PROJECT_MILESTONES_SUCCESS = 'RECEIVE_PROJECT_MILESTONES_SUCCESS'; export const RECEIVE_PROJECT_MILESTONES_ERROR = 'RECEIVE_PROJECT_MILESTONES_ERROR'; + +export const RECEIVE_GROUP_MILESTONES_SUCCESS = 'RECEIVE_GROUP_MILESTONES_SUCCESS'; +export const RECEIVE_GROUP_MILESTONES_ERROR = 'RECEIVE_GROUP_MILESTONES_ERROR'; diff --git a/app/assets/javascripts/milestones/stores/mutations.js b/app/assets/javascripts/milestones/stores/mutations.js index 71331965d2a..601b88cb62a 100644 --- a/app/assets/javascripts/milestones/stores/mutations.js +++ b/app/assets/javascripts/milestones/stores/mutations.js @@ -1,11 +1,16 @@ import Vue from 'vue'; import * as types from './mutation_types'; -import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; export default { [types.SET_PROJECT_ID](state, projectId) { state.projectId = projectId; }, + [types.SET_GROUP_ID](state, groupId) { + state.groupId = groupId; + }, + [types.SET_GROUP_MILESTONES_AVAILABLE](state, groupMilestonesAvailable) { + state.groupMilestonesAvailable = groupMilestonesAvailable; + }, [types.SET_SELECTED_MILESTONES](state, selectedMilestones) { Vue.set(state, 'selectedMilestones', selectedMilestones); }, @@ -32,7 +37,7 @@ export default { }, [types.RECEIVE_PROJECT_MILESTONES_SUCCESS](state, response) { state.matches.projectMilestones = { - list: convertObjectPropsToCamelCase(response.data).map(({ title }) => ({ title })), + list: response.data.map(({ title }) => ({ title })), totalCount: parseInt(response.headers['x-total'], 10), error: null, }; @@ -44,4 +49,18 @@ export default { error, }; }, + [types.RECEIVE_GROUP_MILESTONES_SUCCESS](state, response) { + state.matches.groupMilestones = { + list: response.data.map(({ title }) => ({ title })), + totalCount: parseInt(response.headers['x-total'], 10), + error: null, + }; + }, + [types.RECEIVE_GROUP_MILESTONES_ERROR](state, error) { + state.matches.groupMilestones = { + list: [], + totalCount: 0, + error, + }; + }, }; diff --git a/app/assets/javascripts/milestones/stores/state.js b/app/assets/javascripts/milestones/stores/state.js index 8466228dc17..82723ab32f9 100644 --- a/app/assets/javascripts/milestones/stores/state.js +++ b/app/assets/javascripts/milestones/stores/state.js @@ -1,6 +1,7 @@ export default () => ({ projectId: null, groupId: null, + groupMilestonesAvailable: false, searchQuery: '', matches: { projectMilestones: { @@ -8,6 +9,11 @@ export default () => ({ totalCount: 0, error: null, }, + groupMilestones: { + list: [], + totalCount: 0, + error: null, + }, }, selectedMilestones: [], requestCount: 0, |