diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-11-06 06:08:51 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-11-06 06:08:51 +0000 |
commit | eefbee4451565989727256d36176dc2950e3a0b7 (patch) | |
tree | 29d630cac89ec88ab5c2a22f9b2ca40b4e0fd613 /app/assets/javascripts/search/sidebar | |
parent | 74d35955aa0e12ff6ed99b39adb38e0f13fb96aa (diff) | |
download | gitlab-ce-eefbee4451565989727256d36176dc2950e3a0b7.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/search/sidebar')
6 files changed, 230 insertions, 0 deletions
diff --git a/app/assets/javascripts/search/sidebar/components/confidentiality_filter.vue b/app/assets/javascripts/search/sidebar/components/confidentiality_filter.vue new file mode 100644 index 00000000000..f8938e799aa --- /dev/null +++ b/app/assets/javascripts/search/sidebar/components/confidentiality_filter.vue @@ -0,0 +1,25 @@ +<script> +import { mapState } from 'vuex'; +import { confidentialFilterData } from '../constants/confidential_filter_data'; +import RadioFilter from './radio_filter.vue'; + +export default { + name: 'ConfidentialityFilter', + components: { + RadioFilter, + }, + computed: { + ...mapState(['query']), + showDropdown() { + return Object.values(confidentialFilterData.scopes).includes(this.query.scope); + }, + }, + confidentialFilterData, +}; +</script> + +<template> + <div v-if="showDropdown"> + <radio-filter :filter-data="$options.confidentialFilterData" /> + </div> +</template> diff --git a/app/assets/javascripts/search/sidebar/components/radio_filter.vue b/app/assets/javascripts/search/sidebar/components/radio_filter.vue new file mode 100644 index 00000000000..b27c4e26fb5 --- /dev/null +++ b/app/assets/javascripts/search/sidebar/components/radio_filter.vue @@ -0,0 +1,68 @@ +<script> +import { mapState, mapActions } from 'vuex'; +import { GlFormRadioGroup, GlFormRadio } from '@gitlab/ui'; +import { sprintf, s__ } from '~/locale'; + +export default { + name: 'RadioFilter', + components: { + GlFormRadioGroup, + GlFormRadio, + }, + props: { + filterData: { + type: Object, + required: true, + }, + }, + computed: { + ...mapState(['query']), + ANY() { + return this.filterData.filters.ANY; + }, + scope() { + return this.query.scope; + }, + initialFilter() { + return this.query[this.filterData.filterParam]; + }, + filter() { + return this.initialFilter || this.ANY.value; + }, + filtersArray() { + return this.filterData.filterByScope[this.scope]; + }, + selectedFilter: { + get() { + if (this.filtersArray.some(({ value }) => value === this.filter)) { + return this.filter; + } + + return this.ANY.value; + }, + set(value) { + this.setQuery({ key: this.filterData.filterParam, value }); + }, + }, + }, + methods: { + ...mapActions(['setQuery']), + radioLabel(filter) { + return filter.value === this.ANY.value + ? sprintf(s__('Any %{header}'), { header: this.filterData.header.toLowerCase() }) + : filter.label; + }, + }, +}; +</script> + +<template> + <div> + <h5 class="gl-mt-0">{{ filterData.header }}</h5> + <gl-form-radio-group v-model="selectedFilter"> + <gl-form-radio v-for="f in filtersArray" :key="f.value" :value="f.value"> + {{ radioLabel(f) }} + </gl-form-radio> + </gl-form-radio-group> + </div> +</template> diff --git a/app/assets/javascripts/search/sidebar/components/status_filter.vue b/app/assets/javascripts/search/sidebar/components/status_filter.vue new file mode 100644 index 00000000000..876123ccc52 --- /dev/null +++ b/app/assets/javascripts/search/sidebar/components/status_filter.vue @@ -0,0 +1,25 @@ +<script> +import { mapState } from 'vuex'; +import { stateFilterData } from '../constants/state_filter_data'; +import RadioFilter from './radio_filter.vue'; + +export default { + name: 'StatusFilter', + components: { + RadioFilter, + }, + computed: { + ...mapState(['query']), + showDropdown() { + return Object.values(stateFilterData.scopes).includes(this.query.scope); + }, + }, + stateFilterData, +}; +</script> + +<template> + <div v-if="showDropdown"> + <radio-filter :filter-data="$options.stateFilterData" /> + </div> +</template> diff --git a/app/assets/javascripts/search/sidebar/constants/confidential_filter_data.js b/app/assets/javascripts/search/sidebar/constants/confidential_filter_data.js new file mode 100644 index 00000000000..ecb63ed9eea --- /dev/null +++ b/app/assets/javascripts/search/sidebar/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 const confidentialFilterData = { + header, + filters, + scopes, + filterByScope, + filterParam, +}; diff --git a/app/assets/javascripts/search/sidebar/constants/state_filter_data.js b/app/assets/javascripts/search/sidebar/constants/state_filter_data.js new file mode 100644 index 00000000000..7c9a029ffe4 --- /dev/null +++ b/app/assets/javascripts/search/sidebar/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 const stateFilterData = { + header, + filters, + scopes, + filterByScope, + filterParam, +}; diff --git a/app/assets/javascripts/search/sidebar/index.js b/app/assets/javascripts/search/sidebar/index.js new file mode 100644 index 00000000000..b19016edf3d --- /dev/null +++ b/app/assets/javascripts/search/sidebar/index.js @@ -0,0 +1,34 @@ +import Vue from 'vue'; +import Translate from '~/vue_shared/translate'; +import StatusFilter from './components/status_filter.vue'; +import ConfidentialityFilter from './components/confidentiality_filter.vue'; + +Vue.use(Translate); + +const mountRadioFilters = (store, { id, component }) => { + const el = document.getElementById(id); + + if (!el) return false; + + return new Vue({ + el, + store, + render(createElement) { + 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)); |