Commit e9b379bd authored by Clement Ho's avatar Clement Ho

Add weight filter

parent 90e5de3c
......@@ -50,6 +50,10 @@
icon: 'fa-tag',
hint: 'label:',
tag: '<~label>',
}, {
icon: 'fa-balance-scale',
hint: 'weight:',
tag: '<weight>',
}];
this.droplab.changeHookList(this.hookId, this.dropdown, [droplabFilter], this.config);
......
......@@ -47,6 +47,11 @@
extraArguments: ['labels.json', '~'],
element: document.querySelector('#js-dropdown-label'),
},
weight: {
reference: null,
gl: 'DropdownNonUser',
element: document.querySelector('#js-dropdown-weight'),
},
hint: {
reference: null,
gl: 'DropdownHint',
......
......@@ -19,6 +19,11 @@
type: 'array',
param: 'name[]',
symbol: '~',
}, {
key: 'weight',
type: 'string',
param: '',
symbol: '',
}];
const conditions = [{
......@@ -37,6 +42,14 @@
url: 'label_name[]=No+Label',
tokenKey: 'label',
value: 'none',
}, {
url: 'weight=No+Weight',
tokenKey: 'weight',
value: 'none',
}, {
url: 'weight=Any+Weight',
tokenKey: 'weight',
value: 'any',
}];
class FilteredSearchTokenKeys {
......
......@@ -251,7 +251,8 @@ module ApplicationHelper
author_id: params[:author_id],
author_username: params[:author_username],
search: params[:search],
label_name: params[:label_name]
label_name: params[:label_name],
weight: params[:weight]
}
options = exist_opts.merge(options)
......
......@@ -161,7 +161,7 @@ class Issue < ActiveRecord::Base
end
def self.weight_filter_options
weight_options + [WEIGHT_ALL, WEIGHT_ANY]
WEIGHT_RANGE.to_a
end
def self.weight_options
......
......@@ -29,18 +29,6 @@
.filter-item.inline.labels-filter
= render "shared/issuable/label_dropdown", selected: finder.labels.select(:title).uniq, use_id: false, selected_toggle: params[:label_name], data_options: { field_name: "label_name[]" }
- if local_assigns[:type] == :issues
.filter-item.inline.weight-filter
- if params[:weight]
= hidden_field_tag(:weight, params[:weight])
= dropdown_tag(weight_dropdown_label(params[:weight]), options: { title: "Filter by weight", toggle_class: 'js-weight-select js-filter-submit', dropdown_class: "dropdown-menu-selectable",
placeholder: "Search weight", data: { field_name: "weight" , default_label: "Weight" } }) do
%ul
- Issue.weight_filter_options.each do |weight|
%li
%a{ href: "#", data: { id: weight }, class: ("is-active" if params[:weight] == weight.to_s) }
= weight
- if issuable_filter_present?
.filter-item.inline.reset-filters
%a{ href: page_filter_path(without: issuable_filter_params) } Reset filters
......
......@@ -82,8 +82,22 @@
%span.dropdown-label-box{ style: 'background: {{color}}' }
%span.label-title.js-data-value
{{title}}
#js-dropdown-weight.dropdown-menu{ 'data-dropdown' => true }
%ul{ 'data-dropdown' => true }
%li.filter-dropdown-item{ 'data-value' => 'none' }
%button.btn.btn-link
No Weight
%li.filter-dropdown-item{ 'data-value' => 'any' }
%button.btn.btn-link
Any Weight
%li.divider
%ul.filter-dropdown{ 'data-dropdown' => true }
- Issue.weight_filter_options.each do |weight|
%li.filter-dropdown-item{ 'data-value' => "#{weight}" }
%button.btn.btn-link= weight
.pull-right
= render 'shared/sort_dropdown'
= render 'shared/sort_dropdown', type: local_assigns[:type]
- if @bulk_edit
.issues_bulk_update.hide
......
require 'rails_helper'
describe 'Dropdown weight', js: true, feature: true do
include WaitForAjax
let!(:project) { create(:empty_project) }
let!(:user) { create(:user) }
let(:filtered_search) { find('.filtered-search') }
let(:js_dropdown_weight) { '#js-dropdown-weight' }
def send_keys_to_filtered_search(input)
input.split("").each do |i|
filtered_search.send_keys(i)
sleep 3
wait_for_ajax
end
end
def click_weight(text)
find('#js-dropdown-weight .filter-dropdown .filter-dropdown-item', text: text).click
end
def click_static_weight(text)
find('#js-dropdown-weight .filter-dropdown-item', text: text).click
end
before do
project.team << [user, :master]
login_as(user)
create(:issue, project: project)
visit namespace_project_issues_path(project.namespace, project)
end
describe 'behavior' do
it 'opens when the search bar has weight:' do
filtered_search.set('weight:')
expect(page).to have_css(js_dropdown_weight, visible: true)
end
it 'closes when the search bar is unfocused' do
filtered_search.set('weight:')
find('body').click()
expect(page).to have_css(js_dropdown_weight, visible: false)
end
it 'should load all the weights when opened' do
send_keys_to_filtered_search('weight:')
expect(page.all('#js-dropdown-weight .filter-dropdown .filter-dropdown-item').size).to eq(9)
end
end
describe 'selecting from dropdown' do
before do
filtered_search.set('weight:')
end
it 'fills in weight 1' do
click_weight(1)
expect(page).to have_css(js_dropdown_weight, visible: false)
expect(filtered_search.value).to eq("weight:1")
end
it 'fills in weight 2' do
click_weight(2)
expect(page).to have_css(js_dropdown_weight, visible: false)
expect(filtered_search.value).to eq("weight:2")
end
it 'fills in weight 3' do
click_weight(3)
expect(page).to have_css(js_dropdown_weight, visible: false)
expect(filtered_search.value).to eq("weight:3")
end
it 'fills in `no weight`' do
click_static_weight('No Weight')
expect(page).to have_css(js_dropdown_weight, visible: false)
expect(filtered_search.value).to eq("weight:none")
end
end
describe 'input has existing content' do
it 'opens weight dropdown with existing search term' do
filtered_search.set('searchTerm weight:')
expect(page).to have_css(js_dropdown_weight, visible: true)
end
it 'opens weight dropdown with existing assignee' do
filtered_search.set('assignee:@user weight:')
expect(page).to have_css(js_dropdown_weight, visible: true)
end
it 'opens weight dropdown with existing label' do
filtered_search.set('label:~bug weight:')
expect(page).to have_css(js_dropdown_weight, visible: true)
end
it 'opens weight dropdown with existing milestone' do
filtered_search.set('milestone:%v1.0 weight:')
expect(page).to have_css(js_dropdown_weight, visible: true)
end
end
end
require 'rails_helper'
describe 'Filter issues weight', js: true, feature: true do
include WaitForAjax
let!(:project) { create(:empty_project) }
let!(:user) { create(:user, name: 'administrator', username: 'root') }
let(:filtered_search) { find('.filtered-search') }
let(:js_dropdown_weight) { '#js-dropdown-weight' }
def input_filtered_search(search_term)
filtered_search = find('.filtered-search')
filtered_search.set(search_term)
filtered_search.send_keys(:enter)
end
def expect_filtered_search_input(input)
expect(find('.filtered-search').value).to eq(input)
end
def expect_issues_list_count(open_count, closed_count = 0)
all_count = open_count + closed_count
expect(page).to have_issuable_counts(open: open_count, closed: closed_count, all: all_count)
page.within '.issues-list' do
expect(page).to have_selector('.issue', count: open_count)
end
end
before do
project.team << [user, :master]
login_as(user)
label = create(:label, project: project, title: 'urgent')
milestone = create(:milestone, title: 'version1', project: project)
create(:issue, project: project, weight: 1)
issue = create(:issue,
project: project,
weight: 2,
title: 'Bug report 1',
milestone: milestone,
author: user,
assignee: user)
issue.labels << label
visit namespace_project_issues_path(project.namespace, project)
end
describe 'only weight' do
it 'filter issues by searched weight' do
input_filtered_search('weight:1')
expect_issues_list_count(1)
end
it 'filters issues by invalid weight' do
pending('to be tested, issue #1517')
expect(true).to be(false)
end
it 'filters issues by multiple weights' do
pending('to be tested, issue #1517')
expect(true).to be(false)
end
end
describe 'weight with other filters' do
it 'filters issues by searched weight and text' do
search = "weight:2 bug"
input_filtered_search(search)
expect_issues_list_count(1)
expect_filtered_search_input(search)
end
it 'filters issues by searched weight, author and text' do
search = "weight:2 author:@root bug"
input_filtered_search(search)
expect_issues_list_count(1)
expect_filtered_search_input(search)
end
it 'filters issues by searched weight, author, assignee and text' do
search = "weight:2 author:@root assignee:@root bug"
input_filtered_search(search)
expect_issues_list_count(1)
expect_filtered_search_input(search)
end
it 'filters issues by searched weight, author, assignee, label and text' do
search = "weight:2 author:@root assignee:@root label:~urgent bug"
input_filtered_search(search)
expect_issues_list_count(1)
expect_filtered_search_input(search)
end
it 'filters issues by searched weight, author, assignee, label, milestone and text' do
search = "weight:2 author:@root assignee:@root label:~urgent milestone:%version1 bug"
input_filtered_search(search)
expect_issues_list_count(1)
expect_filtered_search_input(search)
end
end
end
require 'spec_helper'
describe 'Issue sorting by Weight', feature: true do
include SortingHelper
let(:project) { create(:project, :public) }
let(:foo) { create(:issue, title: 'foo', project: project) }
let(:bar) { create(:issue, title: 'bar', project: project) }
before do
login_as :user
end
describe 'sorting by weight' do
before do
foo.update(weight: 5)
bar.update(weight: 10)
end
it 'sorts by more weight' do
visit namespace_project_issues_path(project.namespace, project, sort: sort_value_more_weight)
expect(first_issue).to include('bar')
end
it 'sorts by less weight' do
visit namespace_project_issues_path(project.namespace, project, sort: sort_value_less_weight)
expect(first_issue).to include('foo')
end
end
def first_issue
page.all('ul.issues-list > li').first.text
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