Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-09-15 21:11:29 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-09-15 21:11:29 +0300
commit27d1ed4ddff6c2649544a968c2842140272d9c9d (patch)
tree93a68b94ece233b47284a9c7ad8cabf31465212c /app/assets/javascripts/header_search
parent6e2dde590e694c13efdd441e058a925dcff17258 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/header_search')
-rw-r--r--app/assets/javascripts/header_search/components/app.vue29
-rw-r--r--app/assets/javascripts/header_search/components/header_search_scoped_items.vue31
-rw-r--r--app/assets/javascripts/header_search/constants.js6
-rw-r--r--app/assets/javascripts/header_search/index.js4
-rw-r--r--app/assets/javascripts/header_search/store/actions.js5
-rw-r--r--app/assets/javascripts/header_search/store/getters.js85
-rw-r--r--app/assets/javascripts/header_search/store/index.js8
-rw-r--r--app/assets/javascripts/header_search/store/mutation_types.js1
-rw-r--r--app/assets/javascripts/header_search/store/mutations.js7
-rw-r--r--app/assets/javascripts/header_search/store/state.js4
10 files changed, 174 insertions, 6 deletions
diff --git a/app/assets/javascripts/header_search/components/app.vue b/app/assets/javascripts/header_search/components/app.vue
index cdec3d8eec3..580c27f6c61 100644
--- a/app/assets/javascripts/header_search/components/app.vue
+++ b/app/assets/javascripts/header_search/components/app.vue
@@ -1,7 +1,10 @@
<script>
import { GlSearchBoxByType, GlOutsideDirective as Outside } from '@gitlab/ui';
+import { mapState, mapActions, mapGetters } from 'vuex';
+import { visitUrl } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
import HeaderSearchDefaultItems from './header_search_default_items.vue';
+import HeaderSearchScopedItems from './header_search_scoped_items.vue';
export default {
name: 'HeaderSearchApp',
@@ -12,6 +15,7 @@ export default {
components: {
GlSearchBoxByType,
HeaderSearchDefaultItems,
+ HeaderSearchScopedItems,
},
data() {
return {
@@ -19,17 +23,34 @@ export default {
};
},
computed: {
+ ...mapState(['search']),
+ ...mapGetters(['searchQuery']),
+ searchText: {
+ get() {
+ return this.search;
+ },
+ set(value) {
+ this.setSearch(value);
+ },
+ },
showSearchDropdown() {
return this.showDropdown && gon?.current_username;
},
+ showDefaultItems() {
+ return !this.searchText;
+ },
},
methods: {
+ ...mapActions(['setSearch']),
openDropdown() {
this.showDropdown = true;
},
closeDropdown() {
this.showDropdown = false;
},
+ submitSearch() {
+ return visitUrl(this.searchQuery);
+ },
},
};
</script>
@@ -37,10 +58,13 @@ export default {
<template>
<section v-outside="closeDropdown" class="header-search gl-relative">
<gl-search-box-by-type
+ v-model="searchText"
+ :debounce="500"
autocomplete="off"
:placeholder="$options.i18n.searchPlaceholder"
@focus="openDropdown"
@click="openDropdown"
+ @keydown.enter="submitSearch"
@keydown.esc="closeDropdown"
/>
<div
@@ -49,7 +73,10 @@ export default {
class="header-search-dropdown-menu gl-overflow-y-auto gl-absolute gl-left-0 gl-z-index-1 gl-w-full gl-bg-white gl-border-1 gl-rounded-base gl-border-solid gl-border-gray-200 gl-shadow-x0-y2-b4-s0"
>
<div class="header-search-dropdown-content gl-overflow-y-auto gl-py-2">
- <header-search-default-items />
+ <header-search-default-items v-if="showDefaultItems" />
+ <template v-else>
+ <header-search-scoped-items />
+ </template>
</div>
</div>
</section>
diff --git a/app/assets/javascripts/header_search/components/header_search_scoped_items.vue b/app/assets/javascripts/header_search/components/header_search_scoped_items.vue
new file mode 100644
index 00000000000..645eba05148
--- /dev/null
+++ b/app/assets/javascripts/header_search/components/header_search_scoped_items.vue
@@ -0,0 +1,31 @@
+<script>
+import { GlDropdownItem } from '@gitlab/ui';
+import { mapState, mapGetters } from 'vuex';
+
+export default {
+ name: 'HeaderSearchScopedItems',
+ components: {
+ GlDropdownItem,
+ },
+ computed: {
+ ...mapState(['search']),
+ ...mapGetters(['scopedSearchOptions']),
+ },
+};
+</script>
+
+<template>
+ <div>
+ <gl-dropdown-item
+ v-for="(option, index) in scopedSearchOptions"
+ :id="`scoped-${index}`"
+ :key="index"
+ tabindex="-1"
+ :href="option.url"
+ >
+ "<span class="gl-font-weight-bold">{{ search }}</span
+ >" {{ option.description }}
+ <span v-if="option.scope" class="gl-font-style-italic">{{ option.scope }}</span>
+ </gl-dropdown-item>
+ </div>
+</template>
diff --git a/app/assets/javascripts/header_search/constants.js b/app/assets/javascripts/header_search/constants.js
index 64e56156c2f..fffed7bcbdb 100644
--- a/app/assets/javascripts/header_search/constants.js
+++ b/app/assets/javascripts/header_search/constants.js
@@ -9,3 +9,9 @@ export const MSG_MR_ASSIGNED_TO_ME = __('Merge requests assigned to me');
export const MSG_MR_IM_REVIEWER = __("Merge requests that I'm a reviewer");
export const MSG_MR_IVE_CREATED = __("Merge requests I've created");
+
+export const MSG_IN_ALL_GITLAB = __('in all GitLab');
+
+export const MSG_IN_GROUP = __('in group');
+
+export const MSG_IN_PROJECT = __('in project');
diff --git a/app/assets/javascripts/header_search/index.js b/app/assets/javascripts/header_search/index.js
index 0881db16be3..2d37ee137fc 100644
--- a/app/assets/javascripts/header_search/index.js
+++ b/app/assets/javascripts/header_search/index.js
@@ -12,13 +12,13 @@ export const initHeaderSearchApp = () => {
return false;
}
- const { issuesPath, mrPath } = el.dataset;
+ const { searchPath, issuesPath, mrPath } = el.dataset;
let { searchContext } = el.dataset;
searchContext = JSON.parse(searchContext);
return new Vue({
el,
- store: createStore({ issuesPath, mrPath, searchContext }),
+ store: createStore({ searchPath, issuesPath, mrPath, searchContext }),
render(createElement) {
return createElement(HeaderSearchApp);
},
diff --git a/app/assets/javascripts/header_search/store/actions.js b/app/assets/javascripts/header_search/store/actions.js
new file mode 100644
index 00000000000..841aee04029
--- /dev/null
+++ b/app/assets/javascripts/header_search/store/actions.js
@@ -0,0 +1,5 @@
+import * as types from './mutation_types';
+
+export const setSearch = ({ commit }, value) => {
+ commit(types.SET_SEARCH, value);
+};
diff --git a/app/assets/javascripts/header_search/store/getters.js b/app/assets/javascripts/header_search/store/getters.js
index 1feb0e519ba..d1e1fc8ad73 100644
--- a/app/assets/javascripts/header_search/store/getters.js
+++ b/app/assets/javascripts/header_search/store/getters.js
@@ -1,11 +1,28 @@
+import { objectToQuery } from '~/lib/utils/url_utility';
+
import {
MSG_ISSUES_ASSIGNED_TO_ME,
MSG_ISSUES_IVE_CREATED,
MSG_MR_ASSIGNED_TO_ME,
MSG_MR_IM_REVIEWER,
MSG_MR_IVE_CREATED,
+ MSG_IN_PROJECT,
+ MSG_IN_GROUP,
+ MSG_IN_ALL_GITLAB,
} from '../constants';
+export const searchQuery = (state) => {
+ const query = {
+ search: state.search,
+ nav_source: 'navbar',
+ project_id: state.searchContext.project?.id,
+ group_id: state.searchContext.group?.id,
+ scope: state.searchContext.scope,
+ };
+
+ return `${state.searchPath}?${objectToQuery(query)}`;
+};
+
export const scopedIssuesPath = (state) => {
return (
state.searchContext.project_metadata?.issues_path ||
@@ -48,3 +65,71 @@ export const defaultSearchOptions = (state, getters) => {
},
];
};
+
+export const projectUrl = (state) => {
+ if (!state.searchContext.project || !state.searchContext.group) {
+ return null;
+ }
+
+ const query = {
+ search: state.search,
+ nav_source: 'navbar',
+ project_id: state.searchContext.project.id,
+ group_id: state.searchContext.group.id,
+ scope: state.searchContext.scope,
+ };
+
+ return `${state.searchPath}?${objectToQuery(query)}`;
+};
+
+export const groupUrl = (state) => {
+ if (!state.searchContext.group) {
+ return null;
+ }
+
+ const query = {
+ search: state.search,
+ nav_source: 'navbar',
+ group_id: state.searchContext.group.id,
+ scope: state.searchContext.scope,
+ };
+
+ return `${state.searchPath}?${objectToQuery(query)}`;
+};
+
+export const allUrl = (state) => {
+ const query = {
+ search: state.search,
+ nav_source: 'navbar',
+ scope: state.searchContext.scope,
+ };
+
+ return `${state.searchPath}?${objectToQuery(query)}`;
+};
+
+export const scopedSearchOptions = (state, getters) => {
+ const options = [];
+
+ if (state.searchContext.project) {
+ options.push({
+ scope: state.searchContext.project.name,
+ description: MSG_IN_PROJECT,
+ url: getters.projectUrl,
+ });
+ }
+
+ if (state.searchContext.group) {
+ options.push({
+ scope: state.searchContext.group.name,
+ description: MSG_IN_GROUP,
+ url: getters.groupUrl,
+ });
+ }
+
+ options.push({
+ description: MSG_IN_ALL_GITLAB,
+ url: getters.allUrl,
+ });
+
+ return options;
+};
diff --git a/app/assets/javascripts/header_search/store/index.js b/app/assets/javascripts/header_search/store/index.js
index 066e02aed9f..8b74f8662a5 100644
--- a/app/assets/javascripts/header_search/store/index.js
+++ b/app/assets/javascripts/header_search/store/index.js
@@ -1,13 +1,17 @@
import Vue from 'vue';
import Vuex from 'vuex';
+import * as actions from './actions';
import * as getters from './getters';
+import mutations from './mutations';
import createState from './state';
Vue.use(Vuex);
-export const getStoreConfig = ({ issuesPath, mrPath, searchContext }) => ({
+export const getStoreConfig = ({ searchPath, issuesPath, mrPath, searchContext }) => ({
+ actions,
getters,
- state: createState({ issuesPath, mrPath, searchContext }),
+ mutations,
+ state: createState({ searchPath, issuesPath, mrPath, searchContext }),
});
const createStore = (config) => new Vuex.Store(getStoreConfig(config));
diff --git a/app/assets/javascripts/header_search/store/mutation_types.js b/app/assets/javascripts/header_search/store/mutation_types.js
new file mode 100644
index 00000000000..0bc94ae055f
--- /dev/null
+++ b/app/assets/javascripts/header_search/store/mutation_types.js
@@ -0,0 +1 @@
+export const SET_SEARCH = 'SET_SEARCH';
diff --git a/app/assets/javascripts/header_search/store/mutations.js b/app/assets/javascripts/header_search/store/mutations.js
new file mode 100644
index 00000000000..5b1438929d4
--- /dev/null
+++ b/app/assets/javascripts/header_search/store/mutations.js
@@ -0,0 +1,7 @@
+import * as types from './mutation_types';
+
+export default {
+ [types.SET_SEARCH](state, value) {
+ state.search = value;
+ },
+};
diff --git a/app/assets/javascripts/header_search/store/state.js b/app/assets/javascripts/header_search/store/state.js
index 94a238a24ee..fb2c83dbbe3 100644
--- a/app/assets/javascripts/header_search/store/state.js
+++ b/app/assets/javascripts/header_search/store/state.js
@@ -1,6 +1,8 @@
-const createState = ({ issuesPath, mrPath, searchContext }) => ({
+const createState = ({ searchPath, issuesPath, mrPath, searchContext }) => ({
+ searchPath,
issuesPath,
mrPath,
searchContext,
+ search: '',
});
export default createState;