summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/search/sidebar/components
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/search/sidebar/components')
-rw-r--r--app/assets/javascripts/search/sidebar/components/app.vue41
-rw-r--r--app/assets/javascripts/search/sidebar/components/confidentiality_filter.vue26
-rw-r--r--app/assets/javascripts/search/sidebar/components/radio_filter.vue68
-rw-r--r--app/assets/javascripts/search/sidebar/components/status_filter.vue26
4 files changed, 161 insertions, 0 deletions
diff --git a/app/assets/javascripts/search/sidebar/components/app.vue b/app/assets/javascripts/search/sidebar/components/app.vue
new file mode 100644
index 00000000000..aa11b2025f2
--- /dev/null
+++ b/app/assets/javascripts/search/sidebar/components/app.vue
@@ -0,0 +1,41 @@
+<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-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
new file mode 100644
index 00000000000..38dccb9675d
--- /dev/null
+++ b/app/assets/javascripts/search/sidebar/components/confidentiality_filter.vue
@@ -0,0 +1,26 @@
+<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" />
+ <hr class="gl-my-5 gl-border-gray-100" />
+ </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..5cec2090906
--- /dev/null
+++ b/app/assets/javascripts/search/sidebar/components/status_filter.vue
@@ -0,0 +1,26 @@
+<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" />
+ <hr class="gl-my-5 gl-border-gray-100" />
+ </div>
+</template>