Commit 87722302 authored by Tom Quirk's avatar Tom Quirk

Address frontend reviewer feedback

- touch up specs
- add ability to deselect item
- move select options to constant
parent 57d32dd9
<script> <script>
import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { __ } from '~/locale'; import { __ } from '~/locale';
import { ISSUE_STATUS_SELECT_OPTIONS } from '../constants';
export default { export default {
name: 'StatusSelect', name: 'StatusSelect',
...@@ -15,37 +16,42 @@ export default { ...@@ -15,37 +16,42 @@ export default {
}, },
computed: { computed: {
dropdownText() { dropdownText() {
return this.status?.text ?? __('Select status'); return this.status?.text ?? this.$options.i18n.defaultDropdownText;
}, },
selectedValue() { selectedValue() {
return this.status?.value; return this.status?.value;
}, },
}, },
selectOptions: [ methods: {
{ onDropdownItemClick(statusOption) {
value: 'reopen', // clear status if the currently checked status is clicked again
text: __('Open'), if (this.status?.value === statusOption.value) {
this.status = null;
} else {
this.status = statusOption;
}
}, },
{ },
value: 'close', i18n: {
text: __('Closed'), dropdownTitle: __('Change status'),
}, defaultDropdownText: __('Select status'),
], },
ISSUE_STATUS_SELECT_OPTIONS,
}; };
</script> </script>
<template> <template>
<div> <div>
<input type="hidden" name="update[state_event]" :value="selectedValue" /> <input type="hidden" name="update[state_event]" :value="selectedValue" />
<gl-dropdown :text="dropdownText" :title="__('Change status')" class="gl-w-full"> <gl-dropdown :text="dropdownText" :title="$options.i18n.dropdownTitle" class="gl-w-full">
<gl-dropdown-item <gl-dropdown-item
v-for="item in $options.selectOptions" v-for="statusOption in $options.ISSUE_STATUS_SELECT_OPTIONS"
:key="item.value" :key="statusOption.value"
:is-checked="selectedValue === item.value" :is-checked="selectedValue === statusOption.value"
is-check-item is-check-item
:title="item.text" :title="statusOption.text"
@click="status = item" @click="onDropdownItemClick(statusOption)"
> >
{{ item.text }} {{ statusOption.text }}
</gl-dropdown-item> </gl-dropdown-item>
</gl-dropdown> </gl-dropdown>
</div> </div>
......
import { __ } from '~/locale';
export const ISSUE_STATUS_MODIFIERS = {
REOPEN: 'reopen',
CLOSE: 'close',
};
export const ISSUE_STATUS_SELECT_OPTIONS = [
{
value: ISSUE_STATUS_MODIFIERS.REOPEN,
text: __('Open'),
},
{
value: ISSUE_STATUS_MODIFIERS.CLOSE,
text: __('Closed'),
},
];
import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import StatusSelect from '~/issuable_bulk_update_sidebar/components/status_select.vue'; import StatusSelect from '~/issuable_bulk_update_sidebar/components/status_select.vue';
import { ISSUE_STATUS_SELECT_OPTIONS } from '~/issuable_bulk_update_sidebar/constants';
describe('StatusSelect', () => { describe('StatusSelect', () => {
let wrapper; let wrapper;
...@@ -8,16 +9,24 @@ describe('StatusSelect', () => { ...@@ -8,16 +9,24 @@ describe('StatusSelect', () => {
const findDropdown = () => wrapper.findComponent(GlDropdown); const findDropdown = () => wrapper.findComponent(GlDropdown);
const findAllDropdownItems = () => wrapper.findAllComponents(GlDropdownItem); const findAllDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
const findHiddenInput = () => wrapper.find('input'); const findHiddenInput = () => wrapper.find('input');
function createComponent() { function createComponent() {
wrapper = shallowMount(StatusSelect); wrapper = shallowMount(StatusSelect);
} }
afterEach(() => {
wrapper.destroy();
});
describe('with no value selected', () => { describe('with no value selected', () => {
it('renders default text', () => { beforeEach(() => {
createComponent(); createComponent();
});
it('renders default text', () => {
expect(findDropdown().props('text')).toBe('Select status'); expect(findDropdown().props('text')).toBe('Select status');
}); });
it('renders dropdown items with `is-checked` prop set to `false`', () => { it('renders dropdown items with `is-checked` prop set to `false`', () => {
const dropdownItems = findAllDropdownItems(); const dropdownItems = findAllDropdownItems();
...@@ -27,18 +36,23 @@ describe('StatusSelect', () => { ...@@ -27,18 +36,23 @@ describe('StatusSelect', () => {
}); });
describe('when selecting a value', () => { describe('when selecting a value', () => {
const selectItemAtIndex = 0;
beforeEach(async () => { beforeEach(async () => {
createComponent(); createComponent();
findAllDropdownItems().at(0).vm.$emit('click'); await findAllDropdownItems().at(selectItemAtIndex).vm.$emit('click');
await wrapper.vm.$nextTick();
}); });
it('updates value of the hidden input', () => { it('updates value of the hidden input', () => {
expect(findHiddenInput().attributes('value')).toBe('reopen'); expect(findHiddenInput().attributes('value')).toBe(
ISSUE_STATUS_SELECT_OPTIONS[selectItemAtIndex].value,
);
}); });
it('updates the dropdown text prop', () => { it('updates the dropdown text prop', () => {
expect(findDropdown().props('text')).toBe('Open'); expect(findDropdown().props('text')).toBe(
ISSUE_STATUS_SELECT_OPTIONS[selectItemAtIndex].text,
);
}); });
it('sets dropdown item `is-checked` prop to `true`', () => { it('sets dropdown item `is-checked` prop to `true`', () => {
...@@ -47,5 +61,17 @@ describe('StatusSelect', () => { ...@@ -47,5 +61,17 @@ describe('StatusSelect', () => {
expect(dropdownItems.at(0).props('isChecked')).toBe(true); expect(dropdownItems.at(0).props('isChecked')).toBe(true);
expect(dropdownItems.at(1).props('isChecked')).toBe(false); expect(dropdownItems.at(1).props('isChecked')).toBe(false);
}); });
describe('when selecting the value that is already selected', () => {
it('clears dropdown selection', async () => {
await findAllDropdownItems().at(selectItemAtIndex).vm.$emit('click');
const dropdownItems = findAllDropdownItems();
expect(dropdownItems.at(0).props('isChecked')).toBe(false);
expect(dropdownItems.at(1).props('isChecked')).toBe(false);
expect(findDropdown().props('text')).toBe('Select status');
});
});
}); });
}); });
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