diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-15 15:10:17 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-15 15:10:17 +0300 |
commit | e894595ad8ebdbd565bacaeb126d44f80a636fd8 (patch) | |
tree | 97f898aa3f24b209924bfcee6ee46072807e9b02 /app/assets/javascripts/search | |
parent | a79324ad1f94b0c497a89c1ee35bd7d33f318008 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/search')
7 files changed, 97 insertions, 1 deletions
diff --git a/app/assets/javascripts/search/store/actions.js b/app/assets/javascripts/search/store/actions.js index 447278aa223..082beb5930d 100644 --- a/app/assets/javascripts/search/store/actions.js +++ b/app/assets/javascripts/search/store/actions.js @@ -16,6 +16,28 @@ export const fetchGroups = ({ commit }, search) => { }); }; +export const fetchProjects = ({ commit, state }, search) => { + commit(types.REQUEST_PROJECTS); + const groupId = state.query?.group_id; + const callback = data => { + if (data) { + commit(types.RECEIVE_PROJECTS_SUCCESS, data); + } else { + createFlash({ message: __('There was an error fetching projects') }); + commit(types.RECEIVE_PROJECTS_ERROR); + } + }; + + if (groupId) { + Api.groupProjects(groupId, search, {}, callback); + } else { + // The .catch() is due to the API method not handling a rejection properly + Api.projects(search, { order_by: 'id' }, callback).catch(() => { + callback(); + }); + } +}; + export const setQuery = ({ commit }, { key, value }) => { commit(types.SET_QUERY, { key, value }); }; diff --git a/app/assets/javascripts/search/store/mutation_types.js b/app/assets/javascripts/search/store/mutation_types.js index 2482621d4d7..a6430b53c4f 100644 --- a/app/assets/javascripts/search/store/mutation_types.js +++ b/app/assets/javascripts/search/store/mutation_types.js @@ -2,4 +2,8 @@ export const REQUEST_GROUPS = 'REQUEST_GROUPS'; export const RECEIVE_GROUPS_SUCCESS = 'RECEIVE_GROUPS_SUCCESS'; export const RECEIVE_GROUPS_ERROR = 'RECEIVE_GROUPS_ERROR'; +export const REQUEST_PROJECTS = 'REQUEST_PROJECTS'; +export const RECEIVE_PROJECTS_SUCCESS = 'RECEIVE_PROJECTS_SUCCESS'; +export const RECEIVE_PROJECTS_ERROR = 'RECEIVE_PROJECTS_ERROR'; + export const SET_QUERY = 'SET_QUERY'; diff --git a/app/assets/javascripts/search/store/mutations.js b/app/assets/javascripts/search/store/mutations.js index e57850b870e..91d7cf66c8f 100644 --- a/app/assets/javascripts/search/store/mutations.js +++ b/app/assets/javascripts/search/store/mutations.js @@ -12,6 +12,17 @@ export default { state.fetchingGroups = false; state.groups = []; }, + [types.REQUEST_PROJECTS](state) { + state.fetchingProjects = true; + }, + [types.RECEIVE_PROJECTS_SUCCESS](state, data) { + state.fetchingProjects = false; + state.projects = data; + }, + [types.RECEIVE_PROJECTS_ERROR](state) { + state.fetchingProjects = false; + state.projects = []; + }, [types.SET_QUERY](state, { key, value }) { state.query[key] = value; }, diff --git a/app/assets/javascripts/search/store/state.js b/app/assets/javascripts/search/store/state.js index 70a8aab9998..9a0d61d0b93 100644 --- a/app/assets/javascripts/search/store/state.js +++ b/app/assets/javascripts/search/store/state.js @@ -2,5 +2,7 @@ const createState = ({ query }) => ({ query, groups: [], fetchingGroups: false, + projects: [], + fetchingProjects: false, }); export default createState; diff --git a/app/assets/javascripts/search/topbar/components/project_filter.vue b/app/assets/javascripts/search/topbar/components/project_filter.vue new file mode 100644 index 00000000000..3f1f3848ac7 --- /dev/null +++ b/app/assets/javascripts/search/topbar/components/project_filter.vue @@ -0,0 +1,52 @@ +<script> +import { mapState, mapActions } from 'vuex'; +import { visitUrl, setUrlParams } from '~/lib/utils/url_utility'; +import SearchableDropdown from './searchable_dropdown.vue'; +import { ANY_OPTION, GROUP_DATA, PROJECT_DATA } from '../constants'; + +export default { + name: 'ProjectFilter', + components: { + SearchableDropdown, + }, + props: { + initialData: { + type: Object, + required: false, + default: () => null, + }, + }, + computed: { + ...mapState(['projects', 'fetchingProjects']), + selectedProject() { + return this.initialData ? this.initialData : ANY_OPTION; + }, + }, + methods: { + ...mapActions(['fetchProjects']), + handleProjectChange(project) { + // This determines if we need to update the group filter or not + const queryParams = { + ...(project.namespace_id && { [GROUP_DATA.queryParam]: project.namespace_id }), + [PROJECT_DATA.queryParam]: project.id, + }; + + visitUrl(setUrlParams(queryParams)); + }, + }, + PROJECT_DATA, +}; +</script> + +<template> + <searchable-dropdown + :header-text="$options.PROJECT_DATA.headerText" + :selected-display-value="$options.PROJECT_DATA.selectedDisplayValue" + :items-display-value="$options.PROJECT_DATA.itemsDisplayValue" + :loading="fetchingProjects" + :selected-item="selectedProject" + :items="projects" + @search="fetchProjects" + @change="handleProjectChange" + /> +</template> diff --git a/app/assets/javascripts/search/topbar/components/searchable_dropdown.vue b/app/assets/javascripts/search/topbar/components/searchable_dropdown.vue index 55f3637b015..14577fd7d7a 100644 --- a/app/assets/javascripts/search/topbar/components/searchable_dropdown.vue +++ b/app/assets/javascripts/search/topbar/components/searchable_dropdown.vue @@ -81,7 +81,7 @@ export default { <gl-dropdown class="gl-w-full" menu-class="gl-w-full!" - toggle-class="gl-text-truncate gl-reset-line-height!" + toggle-class="gl-text-truncate" :header-text="headerText" @show="$emit('search', searchText)" @shown="$refs.searchBox.focusInput()" diff --git a/app/assets/javascripts/search/topbar/index.js b/app/assets/javascripts/search/topbar/index.js index a751fa53e03..024544148a0 100644 --- a/app/assets/javascripts/search/topbar/index.js +++ b/app/assets/javascripts/search/topbar/index.js @@ -1,6 +1,7 @@ import Vue from 'vue'; import Translate from '~/vue_shared/translate'; import GroupFilter from './components/group_filter.vue'; +import ProjectFilter from './components/project_filter.vue'; Vue.use(Translate); @@ -33,6 +34,10 @@ const searchableDropdowns = [ id: 'js-search-group-dropdown', component: GroupFilter, }, + { + id: 'js-search-project-dropdown', + component: ProjectFilter, + }, ]; export const initTopbar = store => |