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>2020-11-11 03:08:58 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-11-11 03:08:58 +0300
commit5427433c6d79f9131f4025cabb7e3208380bce9a (patch)
treeea0a22450f467f1ef1e3449255017dbe0f178882 /app/assets/javascripts/search
parent13bcb8221306526671a61df589f7c05505c9934c (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/search')
-rw-r--r--app/assets/javascripts/search/dropdown_filter/components/dropdown_filter.vue108
-rw-r--r--app/assets/javascripts/search/dropdown_filter/constants/confidential_filter_data.js36
-rw-r--r--app/assets/javascripts/search/dropdown_filter/constants/state_filter_data.js42
-rw-r--r--app/assets/javascripts/search/dropdown_filter/index.js38
-rw-r--r--app/assets/javascripts/search/index.js8
-rw-r--r--app/assets/javascripts/search/sidebar/components/app.vue41
-rw-r--r--app/assets/javascripts/search/sidebar/components/confidentiality_filter.vue1
-rw-r--r--app/assets/javascripts/search/sidebar/components/status_filter.vue1
-rw-r--r--app/assets/javascripts/search/sidebar/index.js23
-rw-r--r--app/assets/javascripts/search/store/actions.js9
10 files changed, 250 insertions, 57 deletions
diff --git a/app/assets/javascripts/search/dropdown_filter/components/dropdown_filter.vue b/app/assets/javascripts/search/dropdown_filter/components/dropdown_filter.vue
new file mode 100644
index 00000000000..08619fa2066
--- /dev/null
+++ b/app/assets/javascripts/search/dropdown_filter/components/dropdown_filter.vue
@@ -0,0 +1,108 @@
+<script>
+import { mapState } from 'vuex';
+import { GlDropdown, GlDropdownItem, GlDropdownDivider } from '@gitlab/ui';
+import { setUrlParams, visitUrl } from '~/lib/utils/url_utility';
+import { sprintf, s__ } from '~/locale';
+
+export default {
+ name: 'DropdownFilter',
+ components: {
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownDivider,
+ },
+ props: {
+ filterData: {
+ type: Object,
+ required: true,
+ },
+ },
+ computed: {
+ ...mapState(['query']),
+ scope() {
+ return this.query.scope;
+ },
+ supportedScopes() {
+ return Object.values(this.filterData.scopes);
+ },
+ initialFilter() {
+ return this.query[this.filterData.filterParam];
+ },
+ filter() {
+ return this.initialFilter || this.filterData.filters.ANY.value;
+ },
+ filtersArray() {
+ return this.filterData.filterByScope[this.scope];
+ },
+ selectedFilter: {
+ get() {
+ if (this.filtersArray.some(({ value }) => value === this.filter)) {
+ return this.filter;
+ }
+
+ return this.filterData.filters.ANY.value;
+ },
+ set(filter) {
+ // we need to remove the pagination cursor to ensure the
+ // relevancy of the new results
+
+ visitUrl(
+ setUrlParams({
+ page: null,
+ [this.filterData.filterParam]: filter,
+ }),
+ );
+ },
+ },
+ selectedFilterText() {
+ const f = this.filtersArray.find(({ value }) => value === this.selectedFilter);
+ if (!f || f === this.filterData.filters.ANY) {
+ return sprintf(s__('Any %{header}'), { header: this.filterData.header });
+ }
+
+ return f.label;
+ },
+ showDropdown() {
+ return this.supportedScopes.includes(this.scope);
+ },
+ },
+ methods: {
+ dropDownItemClass(filter) {
+ return {
+ 'gl-border-b-solid gl-border-b-gray-100 gl-border-b-1 gl-pb-2! gl-mb-2':
+ filter === this.filterData.filters.ANY,
+ };
+ },
+ isFilterSelected(filter) {
+ return filter === this.selectedFilter;
+ },
+ handleFilterChange(filter) {
+ this.selectedFilter = filter;
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-dropdown
+ v-if="showDropdown"
+ :text="selectedFilterText"
+ class="col-3 gl-pt-4 gl-pl-0 gl-pr-0 gl-mr-4"
+ menu-class="gl-w-full! gl-pl-0"
+ >
+ <header class="gl-text-center gl-font-weight-bold gl-font-lg">
+ {{ filterData.header }}
+ </header>
+ <gl-dropdown-divider />
+ <gl-dropdown-item
+ v-for="f in filtersArray"
+ :key="f.value"
+ :is-check-item="true"
+ :is-checked="isFilterSelected(f.value)"
+ :class="dropDownItemClass(f)"
+ @click="handleFilterChange(f.value)"
+ >
+ {{ f.label }}
+ </gl-dropdown-item>
+ </gl-dropdown>
+</template>
diff --git a/app/assets/javascripts/search/dropdown_filter/constants/confidential_filter_data.js b/app/assets/javascripts/search/dropdown_filter/constants/confidential_filter_data.js
new file mode 100644
index 00000000000..b29daca89cb
--- /dev/null
+++ b/app/assets/javascripts/search/dropdown_filter/constants/confidential_filter_data.js
@@ -0,0 +1,36 @@
+import { __ } from '~/locale';
+
+const header = __('Confidentiality');
+
+const filters = {
+ ANY: {
+ label: __('Any'),
+ value: null,
+ },
+ CONFIDENTIAL: {
+ label: __('Confidential'),
+ value: 'yes',
+ },
+ NOT_CONFIDENTIAL: {
+ label: __('Not confidential'),
+ value: 'no',
+ },
+};
+
+const scopes = {
+ ISSUES: 'issues',
+};
+
+const filterByScope = {
+ [scopes.ISSUES]: [filters.ANY, filters.CONFIDENTIAL, filters.NOT_CONFIDENTIAL],
+};
+
+const filterParam = 'confidential';
+
+export default {
+ header,
+ filters,
+ scopes,
+ filterByScope,
+ filterParam,
+};
diff --git a/app/assets/javascripts/search/dropdown_filter/constants/state_filter_data.js b/app/assets/javascripts/search/dropdown_filter/constants/state_filter_data.js
new file mode 100644
index 00000000000..0b93aa0be29
--- /dev/null
+++ b/app/assets/javascripts/search/dropdown_filter/constants/state_filter_data.js
@@ -0,0 +1,42 @@
+import { __ } from '~/locale';
+
+const header = __('Status');
+
+const filters = {
+ ANY: {
+ label: __('Any'),
+ value: 'all',
+ },
+ OPEN: {
+ label: __('Open'),
+ value: 'opened',
+ },
+ CLOSED: {
+ label: __('Closed'),
+ value: 'closed',
+ },
+ MERGED: {
+ label: __('Merged'),
+ value: 'merged',
+ },
+};
+
+const scopes = {
+ ISSUES: 'issues',
+ MERGE_REQUESTS: 'merge_requests',
+};
+
+const filterByScope = {
+ [scopes.ISSUES]: [filters.ANY, filters.OPEN, filters.CLOSED],
+ [scopes.MERGE_REQUESTS]: [filters.ANY, filters.OPEN, filters.MERGED, filters.CLOSED],
+};
+
+const filterParam = 'state';
+
+export default {
+ header,
+ filters,
+ scopes,
+ filterByScope,
+ filterParam,
+};
diff --git a/app/assets/javascripts/search/dropdown_filter/index.js b/app/assets/javascripts/search/dropdown_filter/index.js
new file mode 100644
index 00000000000..e5e0745d990
--- /dev/null
+++ b/app/assets/javascripts/search/dropdown_filter/index.js
@@ -0,0 +1,38 @@
+import Vue from 'vue';
+import Translate from '~/vue_shared/translate';
+import DropdownFilter from './components/dropdown_filter.vue';
+import stateFilterData from './constants/state_filter_data';
+import confidentialFilterData from './constants/confidential_filter_data';
+
+Vue.use(Translate);
+
+const mountDropdownFilter = (store, { id, filterData }) => {
+ const el = document.getElementById(id);
+
+ if (!el) return false;
+
+ return new Vue({
+ el,
+ store,
+ render(createElement) {
+ return createElement(DropdownFilter, {
+ props: {
+ filterData,
+ },
+ });
+ },
+ });
+};
+
+const dropdownFilters = [
+ {
+ id: 'js-search-filter-by-state',
+ filterData: stateFilterData,
+ },
+ {
+ id: 'js-search-filter-by-confidential',
+ filterData: confidentialFilterData,
+ },
+];
+
+export default store => [...dropdownFilters].map(filter => mountDropdownFilter(store, filter));
diff --git a/app/assets/javascripts/search/index.js b/app/assets/javascripts/search/index.js
index 7508b3c9a55..275d6351adc 100644
--- a/app/assets/javascripts/search/index.js
+++ b/app/assets/javascripts/search/index.js
@@ -1,11 +1,17 @@
import { queryToObject } from '~/lib/utils/url_utility';
import createStore from './store';
+import initDropdownFilters from './dropdown_filter';
import { initSidebar } from './sidebar';
import initGroupFilter from './group_filter';
export default () => {
const store = createStore({ query: queryToObject(window.location.search) });
- initSidebar(store);
+ if (gon.features.searchFacets) {
+ initSidebar(store);
+ } else {
+ initDropdownFilters(store);
+ }
+
initGroupFilter(store);
};
diff --git a/app/assets/javascripts/search/sidebar/components/app.vue b/app/assets/javascripts/search/sidebar/components/app.vue
deleted file mode 100644
index 0c50f93d381..00000000000
--- a/app/assets/javascripts/search/sidebar/components/app.vue
+++ /dev/null
@@ -1,41 +0,0 @@
-<script>
-import { mapActions, mapState } from 'vuex';
-import { GlButton, GlLink } from '@gitlab/ui';
-import StatusFilter from './status_filter.vue';
-import ConfidentialityFilter from './confidentiality_filter.vue';
-
-export default {
- name: 'GlobalSearchSidebar',
- components: {
- GlButton,
- GlLink,
- StatusFilter,
- ConfidentialityFilter,
- },
- computed: {
- ...mapState(['query']),
- showReset() {
- return this.query.state || this.query.confidential;
- },
- },
- methods: {
- ...mapActions(['applyQuery', 'resetQuery']),
- },
-};
-</script>
-
-<template>
- <form
- class="gl-display-flex gl-flex-direction-column col-md-3 gl-mr-4 gl-mb-6 gl-mb gl-mt-5"
- @submit.prevent="applyQuery"
- >
- <status-filter />
- <confidentiality-filter />
- <div class="gl-display-flex gl-align-items-center gl-mt-3">
- <gl-button variant="success" type="submit">{{ __('Apply') }}</gl-button>
- <gl-link v-if="showReset" class="gl-ml-auto" @click="resetQuery">{{
- __('Reset filters')
- }}</gl-link>
- </div>
- </form>
-</template>
diff --git a/app/assets/javascripts/search/sidebar/components/confidentiality_filter.vue b/app/assets/javascripts/search/sidebar/components/confidentiality_filter.vue
index 38dccb9675d..f8938e799aa 100644
--- a/app/assets/javascripts/search/sidebar/components/confidentiality_filter.vue
+++ b/app/assets/javascripts/search/sidebar/components/confidentiality_filter.vue
@@ -21,6 +21,5 @@ export default {
<template>
<div v-if="showDropdown">
<radio-filter :filter-data="$options.confidentialFilterData" />
- <hr class="gl-my-5 gl-border-gray-100" />
</div>
</template>
diff --git a/app/assets/javascripts/search/sidebar/components/status_filter.vue b/app/assets/javascripts/search/sidebar/components/status_filter.vue
index 5cec2090906..876123ccc52 100644
--- a/app/assets/javascripts/search/sidebar/components/status_filter.vue
+++ b/app/assets/javascripts/search/sidebar/components/status_filter.vue
@@ -21,6 +21,5 @@ export default {
<template>
<div v-if="showDropdown">
<radio-filter :filter-data="$options.stateFilterData" />
- <hr class="gl-my-5 gl-border-gray-100" />
</div>
</template>
diff --git a/app/assets/javascripts/search/sidebar/index.js b/app/assets/javascripts/search/sidebar/index.js
index 6419e8ac2c6..b19016edf3d 100644
--- a/app/assets/javascripts/search/sidebar/index.js
+++ b/app/assets/javascripts/search/sidebar/index.js
@@ -1,11 +1,12 @@
import Vue from 'vue';
import Translate from '~/vue_shared/translate';
-import GlobalSearchSidebar from './components/app.vue';
+import StatusFilter from './components/status_filter.vue';
+import ConfidentialityFilter from './components/confidentiality_filter.vue';
Vue.use(Translate);
-export const initSidebar = store => {
- const el = document.getElementById('js-search-sidebar');
+const mountRadioFilters = (store, { id, component }) => {
+ const el = document.getElementById(id);
if (!el) return false;
@@ -13,7 +14,21 @@ export const initSidebar = store => {
el,
store,
render(createElement) {
- return createElement(GlobalSearchSidebar);
+ return createElement(component);
},
});
};
+
+const radioFilters = [
+ {
+ id: 'js-search-filter-by-state',
+ component: StatusFilter,
+ },
+ {
+ id: 'js-search-filter-by-confidential',
+ component: ConfidentialityFilter,
+ },
+];
+
+export const initSidebar = store =>
+ [...radioFilters].map(filter => mountRadioFilters(store, filter));
diff --git a/app/assets/javascripts/search/store/actions.js b/app/assets/javascripts/search/store/actions.js
index 447278aa223..722ed2eec26 100644
--- a/app/assets/javascripts/search/store/actions.js
+++ b/app/assets/javascripts/search/store/actions.js
@@ -1,7 +1,6 @@
import Api from '~/api';
import createFlash from '~/flash';
import { __ } from '~/locale';
-import { visitUrl, setUrlParams } from '~/lib/utils/url_utility';
import * as types from './mutation_types';
export const fetchGroups = ({ commit }, search) => {
@@ -19,11 +18,3 @@ export const fetchGroups = ({ commit }, search) => {
export const setQuery = ({ commit }, { key, value }) => {
commit(types.SET_QUERY, { key, value });
};
-
-export const applyQuery = ({ state }) => {
- visitUrl(setUrlParams({ ...state.query, page: null }));
-};
-
-export const resetQuery = ({ state }) => {
- visitUrl(setUrlParams({ ...state.query, page: null, state: null, confidential: null }));
-};