Commit 125d7ef6 authored by Jose Ivan Vargas's avatar Jose Ivan Vargas

Merge branch '324246-add-loading-to-filter-body' into 'master'

Add loading prop to filter body and fix search box clear icon

See merge request gitlab-org/gitlab!58223
parents bad3fa34 6fa5f681
<script> <script>
import { GlDropdown, GlSearchBoxByType, GlIcon, GlTruncate, GlDropdownText } from '@gitlab/ui'; import {
GlDropdown,
GlSearchBoxByType,
GlIcon,
GlLoadingIcon,
GlTruncate,
GlDropdownText,
} from '@gitlab/ui';
export default { export default {
components: { components: {
GlDropdown, GlDropdown,
GlSearchBoxByType, GlSearchBoxByType,
GlIcon, GlIcon,
GlLoadingIcon,
GlTruncate, GlTruncate,
GlDropdownText, GlDropdownText,
}, },
...@@ -28,7 +36,15 @@ export default { ...@@ -28,7 +36,15 @@ export default {
required: false, required: false,
default: false, default: false,
}, },
loading: {
type: Boolean,
required: false,
default: false,
},
}, },
data: () => ({
searchBoxText: '',
}),
computed: { computed: {
firstSelectedOption() { firstSelectedOption() {
return this.selectedOptions[0]?.name || '-'; return this.selectedOptions[0]?.name || '-';
...@@ -61,11 +77,13 @@ export default { ...@@ -61,11 +77,13 @@ export default {
class="gl-mt-2 gl-w-full" class="gl-mt-2 gl-w-full"
menu-class="dropdown-extended-height" menu-class="dropdown-extended-height"
:header-text="name" :header-text="name"
:loading="loading"
toggle-class="gl-w-full" toggle-class="gl-w-full"
@show="emitDropdownShow" @show="emitDropdownShow"
@hide="$emit('dropdown-hide')" @hide="$emit('dropdown-hide')"
> >
<template #button-content> <template #button-content>
<gl-loading-icon v-if="loading" class="gl-mr-2" />
<gl-truncate <gl-truncate
:text="firstSelectedOption" :text="firstSelectedOption"
class="gl-min-w-0 gl-mr-2" class="gl-min-w-0 gl-mr-2"
...@@ -80,6 +98,7 @@ export default { ...@@ -80,6 +98,7 @@ export default {
<template v-if="showSearchBox" #header> <template v-if="showSearchBox" #header>
<gl-search-box-by-type <gl-search-box-by-type
ref="searchBox" ref="searchBox"
v-model="searchBoxText"
:placeholder="__('Search')" :placeholder="__('Search')"
autocomplete="off" autocomplete="off"
@input="emitInput" @input="emitInput"
......
...@@ -15,6 +15,11 @@ export default { ...@@ -15,6 +15,11 @@ export default {
required: false, required: false,
default: false, default: false,
}, },
loading: {
type: Boolean,
required: false,
default: false,
},
}, },
data() { data() {
return { return {
...@@ -109,6 +114,7 @@ export default { ...@@ -109,6 +114,7 @@ export default {
:name="filter.name" :name="filter.name"
:selected-options="selectedOptionsOrAll" :selected-options="selectedOptionsOrAll"
:show-search-box="showSearchBox" :show-search-box="showSearchBox"
:loading="loading"
> >
<filter-item <filter-item
v-if="filter.allOption && !searchTerm.length" v-if="filter.allOption && !searchTerm.length"
......
import { GlDropdown, GlSearchBoxByType } from '@gitlab/ui'; import { GlDropdown, GlSearchBoxByType, GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import FilterBody from 'ee/security_dashboard/components/filters/filter_body.vue'; import FilterBody from 'ee/security_dashboard/components/filters/filter_body.vue';
...@@ -80,10 +80,11 @@ describe('Filter Body component', () => { ...@@ -80,10 +80,11 @@ describe('Filter Body component', () => {
expect(spy).toHaveBeenCalledTimes(1); expect(spy).toHaveBeenCalledTimes(1);
}); });
it('emits input event on component when search box input is changed', () => { it('emits input event on component when search box input is changed', async () => {
const text = 'abc'; const text = 'abc';
createComponent({ showSearchBox: true }); createComponent({ showSearchBox: true });
searchBox().vm.$emit('input', text); searchBox().vm.$emit('input', text);
await wrapper.vm.$nextTick();
expect(wrapper.emitted('input')[0][0]).toBe(text); expect(wrapper.emitted('input')[0][0]).toBe(text);
}); });
...@@ -103,4 +104,16 @@ describe('Filter Body component', () => { ...@@ -103,4 +104,16 @@ describe('Filter Body component', () => {
expect(wrapper.text()).toContain('No matching results'); expect(wrapper.text()).toContain('No matching results');
}); });
}); });
describe('loading icon', () => {
it.each`
phrase | loading
${'shows'} | ${true}
${'hides'} | ${false}
`('$phrase the loading icon when the loading prop is $loading', ({ loading }) => {
createComponent({ loading });
expect(wrapper.find(GlLoadingIcon).exists()).toBe(loading);
});
});
}); });
...@@ -23,11 +23,11 @@ const optionIdsAt = (indexes) => optionsAt(indexes).map((x) => x.id); ...@@ -23,11 +23,11 @@ const optionIdsAt = (indexes) => optionsAt(indexes).map((x) => x.id);
describe('Standard Filter component', () => { describe('Standard Filter component', () => {
let wrapper; let wrapper;
const createWrapper = (filterOptions, showSearchBox) => { const createWrapper = (filterOptions, props) => {
wrapper = shallowMount(StandardFilter, { wrapper = shallowMount(StandardFilter, {
localVue, localVue,
router, router,
propsData: { filter: { ...filter, ...filterOptions }, showSearchBox }, propsData: { filter: { ...filter, ...filterOptions }, ...props },
}); });
}; };
...@@ -100,7 +100,7 @@ describe('Standard Filter component', () => { ...@@ -100,7 +100,7 @@ describe('Standard Filter component', () => {
${'shows'} | ${true} ${'shows'} | ${true}
${'does not show'} | ${false} ${'does not show'} | ${false}
`('$phrase search box if showSearchBox is $showSearchBox', ({ showSearchBox }) => { `('$phrase search box if showSearchBox is $showSearchBox', ({ showSearchBox }) => {
createWrapper({}, showSearchBox); createWrapper({}, { showSearchBox });
expect(filterBody().props('showSearchBox')).toBe(showSearchBox); expect(filterBody().props('showSearchBox')).toBe(showSearchBox);
}); });
...@@ -116,6 +116,14 @@ describe('Standard Filter component', () => { ...@@ -116,6 +116,14 @@ describe('Standard Filter component', () => {
}); });
}); });
describe('loading prop', () => {
it.each([true, false])(`sets the filter body loading prop to %s`, (loading) => {
createWrapper({}, { loading });
expect(filterBody().props('loading')).toBe(loading);
});
});
describe('selecting options', () => { describe('selecting options', () => {
beforeEach(() => { beforeEach(() => {
createWrapper({ defaultOptions: optionsAt([1, 2, 3]) }); createWrapper({ defaultOptions: optionsAt([1, 2, 3]) });
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment