Commit 805b4cf5 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'ui/issuable-filter' into 'master'

UI: Issuable filter tweaks

Depends on !1953

See the commits for more details, the messages mostly speak for themselves.

# Highlights

## Filter bar

Before:

![filter_before](/uploads/b061be7521c6d5babb77c7d12e77f65e/filter_before.png)

After:

![filter_after](/uploads/aadfbcd77caf1b49fde8ca6d781f1004/filter_after.png)

## Bulk edit bar

Before:

![bulk_before](/uploads/849c98224e1f335c65c0de5616bbcdae/bulk_before.png)

After:

![bulk_after](/uploads/185d29116663f9f663acab76d328096f/bulk_after.png)


See merge request !1963
parents 15ea1285 494ebad3
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
$('#filter_issue_search').val($('#issue_search').val()) $('#filter_issue_search').val($('#issue_search').val())
initSelects: -> initSelects: ->
$("select#update_status").select2(width: 'resolve', dropdownAutoWidth: true) $("select#update_state_event").select2(width: 'resolve', dropdownAutoWidth: true)
$("select#update_assignee_id").select2(width: 'resolve', dropdownAutoWidth: true) $("select#update_assignee_id").select2(width: 'resolve', dropdownAutoWidth: true)
$("select#update_milestone_id").select2(width: 'resolve', dropdownAutoWidth: true) $("select#update_milestone_id").select2(width: 'resolve', dropdownAutoWidth: true)
$("select#label_name").select2(width: 'resolve', dropdownAutoWidth: true) $("select#label_name").select2(width: 'resolve', dropdownAutoWidth: true)
......
...@@ -32,17 +32,15 @@ class @UsersSelect ...@@ -32,17 +32,15 @@ class @UsersSelect
if showNullUser if showNullUser
nullUser = { nullUser = {
name: 'Unassigned', name: 'Unassigned',
avatar: null,
username: 'none',
id: 0 id: 0
} }
data.results.unshift(nullUser) data.results.unshift(nullUser)
if showAnyUser if showAnyUser
name = showAnyUser
name = 'Any User' if name == true
anyUser = { anyUser = {
name: 'Any', name: name,
avatar: null,
username: 'none',
id: null id: null
} }
data.results.unshift(anyUser) data.results.unshift(anyUser)
...@@ -50,7 +48,6 @@ class @UsersSelect ...@@ -50,7 +48,6 @@ class @UsersSelect
if showEmailUser && data.results.length == 0 && query.term.match(/^[^@]+@[^@]+$/) if showEmailUser && data.results.length == 0 && query.term.match(/^[^@]+@[^@]+$/)
emailUser = { emailUser = {
name: "Invite \"#{query.term}\"", name: "Invite \"#{query.term}\"",
avatar: null,
username: query.term, username: query.term,
id: query.term id: query.term
} }
...@@ -82,10 +79,10 @@ class @UsersSelect ...@@ -82,10 +79,10 @@ class @UsersSelect
else else
avatar = gon.default_avatar_url avatar = gon.default_avatar_url
"<div class='user-result'> "<div class='user-result #{'no-username' unless user.username}'>
<div class='user-image'><img class='avatar s24' src='#{avatar}'></div> <div class='user-image'><img class='avatar s24' src='#{avatar}'></div>
<div class='user-name'>#{user.name}</div> <div class='user-name'>#{user.name}</div>
<div class='user-username'>#{user.username}</div> <div class='user-username'>#{user.username || ""}</div>
</div>" </div>"
formatSelection: (user) -> formatSelection: (user) ->
......
...@@ -15,6 +15,16 @@ ...@@ -15,6 +15,16 @@
border-left: none; border-left: none;
padding-top: 5px; padding-top: 5px;
} }
.select2-chosen {
color: $gl-text-color;
}
&.select2-default {
.select2-chosen {
color: #999;
}
}
} }
} }
...@@ -23,6 +33,7 @@ ...@@ -23,6 +33,7 @@
border: 1px solid #e7e9ed; border: 1px solid #e7e9ed;
} }
.select2-drop { .select2-drop {
@include box-shadow(rgba(76, 86, 103, 0.247059) 0px 0px 1px 0px, rgba(31, 37, 50, 0.317647) 0px 2px 18px 0px); @include box-shadow(rgba(76, 86, 103, 0.247059) 0px 0px 1px 0px, rgba(31, 37, 50, 0.317647) 0px 2px 18px 0px);
@include border-radius (0px); @include border-radius (0px);
...@@ -123,10 +134,16 @@ ...@@ -123,10 +134,16 @@
} }
.user-result { .user-result {
min-height: 24px;
.user-image { .user-image {
float: left; float: left;
} }
.user-name {
&.no-username {
.user-name {
line-height: 24px;
}
} }
} }
......
...@@ -44,9 +44,10 @@ module IssuesHelper ...@@ -44,9 +44,10 @@ module IssuesHelper
end end
def bulk_update_milestone_options def bulk_update_milestone_options
options_for_select([['None (backlog)', -1]]) + milestones = project_active_milestones.to_a
options_from_collection_for_select(project_active_milestones, 'id', milestones.unshift(Milestone::None)
'title', params[:milestone_id])
options_from_collection_for_select(milestones, 'id', 'title', params[:milestone_id])
end end
def milestone_options(object) def milestone_options(object)
......
...@@ -15,12 +15,14 @@ module SelectsHelper ...@@ -15,12 +15,14 @@ module SelectsHelper
html = { html = {
class: css_class, class: css_class,
'data-placeholder' => placeholder, data: {
'data-null-user' => null_user, placeholder: placeholder,
'data-any-user' => any_user, null_user: null_user,
'data-email-user' => email_user, any_user: any_user,
'data-first-user' => first_user, email_user: email_user,
'data-current-user' => current_user first_user: first_user,
current_user: current_user
}
} }
unless opts[:scope] == :all unless opts[:scope] == :all
......
...@@ -17,7 +17,7 @@ class Label < ActiveRecord::Base ...@@ -17,7 +17,7 @@ class Label < ActiveRecord::Base
# Requests that have no label assigned. # Requests that have no label assigned.
LabelStruct = Struct.new(:title, :name) LabelStruct = Struct.new(:title, :name)
None = LabelStruct.new('No Label', 'No Label') None = LabelStruct.new('No Label', 'No Label')
Any = LabelStruct.new('Any', '') Any = LabelStruct.new('Any Label', '')
DEFAULT_COLOR = '#428BCA' DEFAULT_COLOR = '#428BCA'
......
...@@ -16,9 +16,9 @@ ...@@ -16,9 +16,9 @@
class Milestone < ActiveRecord::Base class Milestone < ActiveRecord::Base
# Represents a "No Milestone" state used for filtering Issues and Merge # Represents a "No Milestone" state used for filtering Issues and Merge
# Requests that have no milestone assigned. # Requests that have no milestone assigned.
MilestoneStruct = Struct.new(:title, :name) MilestoneStruct = Struct.new(:title, :name, :id)
None = MilestoneStruct.new('No Milestone', 'No Milestone') None = MilestoneStruct.new('No Milestone', 'No Milestone', 0)
Any = MilestoneStruct.new('Any', '') Any = MilestoneStruct.new('Any Milestone', '', -1)
include InternalId include InternalId
include Sortable include Sortable
......
...@@ -31,11 +31,11 @@ ...@@ -31,11 +31,11 @@
.issues-other-filters .issues-other-filters
.filter-item.inline .filter-item.inline
= users_select_tag(:assignee_id, selected: params[:assignee_id], = users_select_tag(:assignee_id, selected: params[:assignee_id],
placeholder: 'Assignee', class: 'trigger-submit', any_user: true, null_user: true, first_user: true, current_user: true) placeholder: 'Assignee', class: 'trigger-submit', any_user: "Any Assignee", null_user: true, first_user: true, current_user: true)
.filter-item.inline .filter-item.inline
= users_select_tag(:author_id, selected: params[:author_id], = users_select_tag(:author_id, selected: params[:author_id],
placeholder: 'Author', class: 'trigger-submit', any_user: true, first_user: true, current_user: true) placeholder: 'Author', class: 'trigger-submit', any_user: "Any Author", first_user: true, current_user: true)
.filter-item.inline.milestone-filter .filter-item.inline.milestone-filter
= select_tag('milestone_title', projects_milestones_options, = select_tag('milestone_title', projects_milestones_options,
...@@ -53,12 +53,16 @@ ...@@ -53,12 +53,16 @@
- if controller.controller_name == 'issues' - if controller.controller_name == 'issues'
.issues_bulk_update.hide .issues_bulk_update.hide
= form_tag bulk_update_namespace_project_issues_path(@project.namespace, @project), method: :post do = form_tag bulk_update_namespace_project_issues_path(@project.namespace, @project), method: :post do
= select_tag('update[state_event]', options_for_select([['Open', 'reopen'], ['Closed', 'close']]), prompt: "Status", class: 'form-control') .filter-item.inline
= users_select_tag('update[assignee_id]', placeholder: 'Assignee', null_user: true, first_user: true, current_user: true) = select_tag('update[state_event]', options_for_select([['Open', 'reopen'], ['Closed', 'close']]), include_blank: true, data: { placeholder: "Status" })
= select_tag('update[milestone_id]', bulk_update_milestone_options, prompt: "Milestone") .filter-item.inline
= users_select_tag('update[assignee_id]', placeholder: 'Assignee', null_user: true, first_user: true, current_user: true)
.filter-item.inline
= select_tag('update[milestone_id]', bulk_update_milestone_options, include_blank: true, data: { placeholder: "Milestone" })
= hidden_field_tag 'update[issues_ids]', [] = hidden_field_tag 'update[issues_ids]', []
= hidden_field_tag :state_event, params[:state_event] = hidden_field_tag :state_event, params[:state_event]
= button_tag "Update issues", class: "btn update_selected_issues btn-save" .filter-item.inline
= button_tag "Update issues", class: "btn update_selected_issues btn-save"
:javascript :javascript
new UsersSelect(); new UsersSelect();
......
...@@ -65,7 +65,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps ...@@ -65,7 +65,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
step 'I see current user as the first user' do step 'I see current user as the first user' do
expect(page).to have_selector('.user-result', visible: true, count: 4) expect(page).to have_selector('.user-result', visible: true, count: 4)
users = page.all('.user-name') users = page.all('.user-name')
expect(users[0].text).to eq 'Any' expect(users[0].text).to eq 'Any Assignee'
expect(users[1].text).to eq 'Unassigned' expect(users[1].text).to eq 'Unassigned'
expect(users[2].text).to eq current_user.name expect(users[2].text).to eq current_user.name
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