Commit 52f8ae1e authored by charlieablett's avatar charlieablett

Modify weight values

- `null` means "Any weight"
- `-1` means "No weight"
- 0 now means "0 weight"
- Update frontend weight dropdown
- Update backend weight filters
- Add failing tests for weight values
- Fix weight selection for no / any / 0 weight
- Fix issue filtering by weight
- Modify IssuesFinder for no-weight filtering
- Update tests for 'any' filter to include all issues regardless
of weight (even no weight)
parent 8be301fe
<script>
/* eslint-disable vue/require-default-prop */
import WeightSelect from 'ee/weight_select';
import { GlLoadingIcon } from '@gitlab/ui';
const ANY_WEIGHT = 'Any Weight';
const NO_WEIGHT = 'No Weight';
const ANY_WEIGHT_LABEL = 'Any Weight';
const NO_WEIGHT_LABEL = 'No Weight';
const NO_WEIGHT_STR_VALUE = 'None';
const ANY_WEIGHT_STR_VALUE = 'Any';
const NO_WEIGHT_INT_VALUE = -1;
const ANY_WEIGHT_INT_VALUE = null;
export default {
components: {
......@@ -19,6 +23,7 @@ export default {
value: {
type: [Number, String],
required: false,
default: ANY_WEIGHT_INT_VALUE,
},
canEdit: {
type: Boolean,
......@@ -37,15 +42,15 @@ export default {
},
computed: {
valueClass() {
if (this.valueText === ANY_WEIGHT) {
if (this.value === ANY_WEIGHT_INT_VALUE) {
return 'text-secondary';
}
return 'bold';
},
valueText() {
if (this.value > 0) return this.value;
if (this.value === 0) return NO_WEIGHT;
return ANY_WEIGHT;
if (this.value === NO_WEIGHT_INT_VALUE) return NO_WEIGHT_LABEL;
if (this.value === ANY_WEIGHT_INT_VALUE) return ANY_WEIGHT_LABEL;
return this.value;
},
},
mounted() {
......@@ -56,17 +61,30 @@ export default {
});
},
methods: {
isSelected(weight) {
if (this.value === NO_WEIGHT_INT_VALUE) {
return weight === NO_WEIGHT_STR_VALUE;
}
if (this.value === ANY_WEIGHT_INT_VALUE) {
return weight === ANY_WEIGHT_STR_VALUE;
}
return this.value === weight;
},
selectWeight(weight) {
this.board.weight = this.weightInt(weight);
},
weightInt(weight) {
if (weight > 0) {
return weight;
if (weight === NO_WEIGHT_STR_VALUE) {
return NO_WEIGHT_INT_VALUE;
}
if (weight === NO_WEIGHT) {
return 0;
if (weight === ANY_WEIGHT_STR_VALUE) {
return ANY_WEIGHT_INT_VALUE;
}
return -1;
return weight;
},
},
};
......@@ -96,7 +114,7 @@ export default {
<div class="dropdown-content ">
<ul>
<li v-for="weight in weights" :key="weight">
<a :class="{ 'is-active': weight == valueText }" :data-id="weight" href="#">
<a :class="{ 'is-active': isSelected(weight) }" :data-id="weight" href="#">
{{ weight }}
</a>
</li>
......
......@@ -27,9 +27,9 @@ module EE
return items unless weights?
if filter_by_no_weight?
items.where(weight: [-1, nil])
items.where(weight: nil)
elsif filter_by_any_weight?
items.where.not(weight: [-1, nil])
items
else
items.where(weight: params[:weight])
end
......
......@@ -151,6 +151,7 @@ describe 'Scoped issue boards', :js do
context 'weight' do
let!(:issue_weight_1) { create(:issue, project: project, weight: 1) }
let!(:issue_weight_none) { create(:issue, project: project, weight: nil) }
it 'creates board filtering by weight' do
create_board_weight(1)
......@@ -173,6 +174,12 @@ describe 'Scoped issue boards', :js do
expect(page).to have_selector('.board-card', count: 4)
end
it 'creates board filtering by "None" weight' do
create_board_weight('None')
expect(page).to have_selector('.board-card', count: 5)
end
it 'displays dot highlight and tooltip' do
create_board_weight(1)
......
......@@ -11,12 +11,13 @@ describe IssuesFinder do
describe 'filter by weight' do
set(:issue_with_weight_1) { create(:issue, project: project3, weight: 1) }
set(:issue_with_weight_42) { create(:issue, project: project3, weight: 42) }
set(:issue_with_no_weight) { create(:issue, project: project3, weight: nil) }
context 'filter issues with no weight' do
let(:params) { { weight: Issue::WEIGHT_NONE } }
it 'returns all issues' do
expect(issues).to contain_exactly(issue1, issue2, issue3, issue4)
it 'returns all issues with nil weight' do
expect(issues).to contain_exactly(issue_with_no_weight, issue1, issue2, issue3, issue4)
end
end
......@@ -24,14 +25,14 @@ describe IssuesFinder do
let(:params) { { weight: Issue::WEIGHT_ANY } }
it 'returns all issues' do
expect(issues).to contain_exactly(issue_with_weight_1, issue_with_weight_42)
expect(issues).to contain_exactly(issue_with_weight_1, issue_with_weight_42, issue_with_no_weight, issue1, issue2, issue3, issue4)
end
end
context 'filter issues with a specific weight' do
let(:params) { { weight: 42 } }
it 'returns all issues' do
it 'returns all issues with that weight' do
expect(issues).to contain_exactly(issue_with_weight_42)
end
end
......
......@@ -4,7 +4,14 @@ import IssuableContext from '~/issuable_context';
let vm;
let board;
const weights = ['Any Weight', 'No Weight', 1, 2, 3];
const expectedDropdownValues = {
anyWeight: 'Any',
noWeight: 'None',
};
// see ee/app/views/shared/boards/_switcher.html.haml
const weights = ['Any', 'None', 0, 1, 2, 3];
function getSelectedText() {
return vm.$el.querySelector('.value').innerText.trim();
......@@ -43,23 +50,31 @@ describe('WeightSelect', () => {
expect(getSelectedText()).toBe('Any Weight');
});
it('displays Any Weight for value -1', done => {
vm.value = -1;
it('displays Any Weight for null', done => {
vm.value = null;
Vue.nextTick(() => {
expect(getSelectedText()).toEqual('Any Weight');
done();
});
});
it('displays No Weight', done => {
vm.value = 0;
it('displays No Weight for -1', done => {
vm.value = -1;
Vue.nextTick(() => {
expect(getSelectedText()).toEqual('No Weight');
done();
});
});
it('weight 1', done => {
it('displays weight for 0', done => {
vm.value = 0;
Vue.nextTick(() => {
expect(getSelectedText()).toEqual('0');
done();
});
});
it('displays weight for 1', done => {
vm.value = 1;
Vue.nextTick(() => {
expect(getSelectedText()).toEqual('1');
......@@ -73,17 +88,17 @@ describe('WeightSelect', () => {
vm.$el.querySelector('.edit-link').click();
setTimeout(() => {
expect(activeDropdownItem()).toEqual('Any Weight');
expect(activeDropdownItem()).toEqual(expectedDropdownValues.anyWeight);
done();
});
});
it('shows No Weight', done => {
vm.value = 0;
vm.value = -1;
vm.$el.querySelector('.edit-link').click();
setTimeout(() => {
expect(activeDropdownItem()).toEqual('No Weight');
expect(activeDropdownItem()).toEqual(expectedDropdownValues.noWeight);
done();
});
});
......@@ -103,9 +118,10 @@ describe('WeightSelect', () => {
it('sets value', done => {
vm.$el.querySelector('.edit-link').click();
setTimeout(() => {
vm.$el.querySelectorAll('li a')[3].click();
});
const dropdownItem = vm.$el.querySelectorAll('li a')[4];
expect(dropdownItem.innerText).toBe('2');
dropdownItem.click();
setTimeout(() => {
expect(activeDropdownItem()).toEqual('2');
......@@ -123,8 +139,8 @@ describe('WeightSelect', () => {
});
setTimeout(() => {
expect(activeDropdownItem()).toEqual('Any Weight');
expect(board.weight).toEqual(-1);
expect(activeDropdownItem()).toEqual(expectedDropdownValues.anyWeight);
expect(board.weight).toEqual(null);
done();
});
});
......@@ -138,8 +154,8 @@ describe('WeightSelect', () => {
});
setTimeout(() => {
expect(activeDropdownItem()).toEqual('No Weight');
expect(board.weight).toEqual(0);
expect(activeDropdownItem()).toEqual(expectedDropdownValues.noWeight);
expect(board.weight).toEqual(-1);
done();
});
});
......
......@@ -57,7 +57,7 @@ describe API::Issues, :mailer do
it 'returns issues with any weight' do
get api('/issues', user), params: { weight: 'Any', scope: 'all' }
expect_paginated_array_response([issue3.id, issue2.id, issue1.id])
expect_paginated_array_response([issue.id, issue3.id, issue2.id, issue1.id])
end
end
......
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