search: style search detail, add detail link

This commit is contained in:
Felix Niklas 2016-07-05 17:06:00 +02:00
parent d002da8a64
commit 613cc7ef20
10 changed files with 229 additions and 145 deletions

View file

@ -3,24 +3,26 @@ class App.Navigation extends App.ControllerWidgetPermanent
elements:
'#global-search': 'searchInput'
'#global-search-result': 'searchResult'
'.js-global-search-result': 'searchResult'
'.search': 'searchContainer'
events:
'click .js-toggleNotifications': 'toggleNotifications'
'click .js-emptySearch': 'emptyAndClose'
'dblclick .search-holder .icon-magnifier': 'openExtendedSearch'
'submit form.search-holder': 'preventDefault'
'focus #global-search': 'searchFocus'
'blur #global-search': 'searchBlur'
'keydown #global-search': 'listNavigate'
'click #global-search-result': 'andClose'
'click .js-global-search-result': 'andClose'
'change .js-menu .js-switch input': 'switch'
'click .js-details-link': 'openExtendedSearch'
constructor: ->
super
@render()
@throttledSearch = _.throttle @search, 200
# rerender view, e. g. on langauge change
@bind 'ui:rerender', =>
@renderMenu()
@ -195,7 +197,7 @@ class App.Navigation extends App.ControllerWidgetPermanent
@query = '' # reset query cache
@searchContainer.addClass('focused')
@anyPopoversDestroy()
@searchFunction(0)
@search()
searchBlur: (e) =>
@ -220,7 +222,7 @@ class App.Navigation extends App.ControllerWidgetPermanent
@nudge(e, 1)
return
else if e.keyCode is 13 # enter
href = @$('#global-search-result .nav-tab.is-hover').attr('href')
href = @$('.global-search-result .nav-tab.is-hover').attr('href')
return if !href
@locationExecute(href)
@emptyAndClose()
@ -228,7 +230,7 @@ class App.Navigation extends App.ControllerWidgetPermanent
return
# on other keys, show result
@searchFunction(200)
@throttledSearch()
nudge: (e, position) =>
@ -266,9 +268,7 @@ class App.Navigation extends App.ControllerWidgetPermanent
@searchContainer.removeClass('open')
@delay(@anyPopoversDestroy, 100, 'removePopovers')
searchFunction: (delay) =>
search = =>
search: =>
query = @searchInput.val().trim()
return if !query
return if query is @query
@ -319,7 +319,6 @@ class App.Navigation extends App.ControllerWidgetPermanent
@renderResult(result)
)
@delay(search, delay, 'search')
getItems: (data) ->
navbar = _.values(data.navbar)
@ -479,7 +478,8 @@ class App.Navigation extends App.ControllerWidgetPermanent
e.stopPropagation()
@notificationWidget.toggle()
openExtendedSearch: =>
openExtendedSearch: (event) ->
event.preventDefault()
query = @searchInput.val()
@searchInput.val('').blur()
if query
@ -487,4 +487,6 @@ class App.Navigation extends App.ControllerWidgetPermanent
return
@navigate('#search')
App.Config.set('navigation', App.Navigation, 'Navigations')

View file

@ -4,9 +4,11 @@ class App.Search extends App.Controller
'.js-search': 'searchInput'
events:
'click .js-emptySearch': 'empty'
'submit form.search-holder': 'preventDefault'
'keydown .js-search': 'listNavigate'
'click .js-tab': 'showTab'
'input .js-search': 'updateFilledClass'
constructor: ->
super
@ -19,18 +21,21 @@ class App.Search extends App.Controller
# update taskbar with new meta data
App.TaskManager.touch(@task_key)
@throttledSearch = _.throttle @search, 200
@render()
meta: =>
title = App.i18n.translateInline('Extended Search')
if @query
title += ": #{App.Utils.htmlEscape(@query)}"
title = App.Utils.htmlEscape(@query)
else
title = App.i18n.translateInline('Extended Search')
meta =
url: @url()
id: ''
head: title
title: title
iconClass: 'magnifier'
iconClass: 'searchdetail'
meta
url: ->
@ -38,10 +43,9 @@ class App.Search extends App.Controller
show: (params) =>
@navupdate(url: '#search', type: 'menu')
console.log('par', params)
return if !params.query
@$('.js-search').val(decodeURIComponent(params.query)).trigger('change')
@searchFunction(200, true)
@throttledSearch(true)
hide: ->
# nothing
@ -79,7 +83,7 @@ class App.Search extends App.Controller
)
if @query
@searchFunction(200, true)
@throttledSearch(true)
listNavigate: (e) =>
if e.keyCode is 27 # close on esc
@ -87,17 +91,16 @@ class App.Search extends App.Controller
return
# on other keys, show result
@searchFunction(200)
@throttledSearch(200)
empty: =>
@searchInput.val('')
@updateFilledClass()
# remove not needed popovers
@delay(@anyPopoversDestroy, 100, 'removePopovers')
searchFunction: (delay, force = false) =>
search = =>
search: (force = false) =>
query = @searchInput.val().trim()
if !force
return if !query
@ -151,7 +154,6 @@ class App.Search extends App.Controller
@renderResult(result)
)
@delay(search, delay, 'search')
renderResult: (result = []) =>
@result = result
@ -161,7 +163,7 @@ class App.Search extends App.Controller
count = result[tab.model].length
if @model is tab.model
@renderTab(tab.model, result[tab.model] || [])
@$(".js-tab#{tab.model} .js-counter").text("(#{count})")
@$(".js-tab#{tab.model} .js-counter").text(count)
showTab: (e) =>
tabs = $(e.currentTarget).closest('.tabs')
@ -213,6 +215,9 @@ class App.Search extends App.Controller
App.TaskManager.update(@task_key, { state: current })
App.TaskManager.touch(@task_key)
updateFilledClass: ->
@searchInput.toggleClass 'is-empty', !@searchInput.val()
class Router extends App.ControllerPermanent
constructor: (params) ->
super

View file

@ -10,7 +10,18 @@
<%- @Icon('logo') %>
<div class="activity-counter js-notificationsCounter"></div>
</div>
<ul id="global-search-result" class="custom-dropdown-menu" role="menu"></ul>
<div class="global-search-menu">
<a href="#search" class="global-search-detail-link nav-tab nav-tab--search js-details-link">
<div class="nav-tab-icon">
<%- @Icon('searchdetail') %>
</div>
<div class="nav-tab-name flex u-textTruncate">
<%= @T('Show Search Details') %>
<%- @Icon('long-arrow-right') %>
</div>
</a>
<ul class="global-search-result js-global-search-result" role="menu"></ul>
</div>
</div>
<div class="menu js-menu"></div>
<div class="tasks tasks-navigation"></div>

View file

@ -1,8 +1,10 @@
<div class="flex vertical">
<div class="flex main vertical">
<div class="detail-search">
<div class="detail-search-header">
<div class="searchfield">
<%- @Icon('magnifier') %>
<input class="js-search form-control" name="query" placeholder="<%- @Ti('Find what you search. E. g. "search phrase"') %>" value="<%= @query %>" type="search" autocomplete="off">
<input class="js-search form-control<%= if !@query then ' is-empty' %>" name="query" placeholder="<%- @Ti('Find what you search. E. g. "search phrase"') %>" value="<%= @query %>" type="search" autocomplete="off">
<div class="empty-search js-emptySearch">
<%- @Icon('diagonal-cross') %>
</div>
@ -10,10 +12,15 @@
<div class="tabs tabs-wide">
<% for tab in @tabs: %>
<div data-tab-content="<%- tab.model %>" class="tab js-tab js-tab<%- tab.model %><% if tab.active: %> active<% end %>"><%- @T(tab.name) %> <span class="js-counter"><%- tab.count %></span></div>
<div data-tab-content="<%- tab.model %>" class="tab js-tab js-tab<%- tab.model %><% if tab.active: %> active<% end %>">
<span class="tab-name"><%- @T(tab.name) %></span>
<span class="tab-badge js-counter"><%- tab.count %></span>
</div>
<% end %>
</div>
</div>
<div class="js-content"></div>
</div>
</div>

View file

@ -70,6 +70,7 @@
.icon-reply-all { width: 16px; height: 16px; }
.icon-reply { width: 16px; height: 16px; }
.icon-report { width: 20px; height: 20px; }
.icon-searchdetail { width: 18px; height: 14px; }
.icon-signout { width: 15px; height: 19px; }
.icon-small-dot { width: 16px; height: 16px; }
.icon-split { width: 16px; height: 16px; }

View file

@ -1800,12 +1800,27 @@ input.has-error {
appearance: textfield;
border-radius: 19px;
padding: 0 17px 0 42px;
&.is-empty + .empty-search {
visibility: hidden;
}
}
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
.empty-search {
height: 41px;
width: 50px;
visibility: visible;
.icon {
position: static;
opacity: 0.5;
}
}
}
.content {
@ -3038,19 +3053,17 @@ footer {
}
.nav-tab-icon {
margin-right: 7px;
margin-left: 7px;
margin-top: -3px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
width: 16px;
width: 30px;
}
.nav-tab-icon .icon {
width: 16px;
height: 16px;
max-width: 18px;
max-height: 18px;
fill: #808080;
}
@ -3193,7 +3206,7 @@ footer {
cursor: pointer;
}
.empty-search .icon-diagonal-cross {
.search .empty-search .icon-diagonal-cross {
fill: white;
opacity: 0.5;
}
@ -3272,10 +3285,7 @@ footer {
display: none;
}
.search .custom-dropdown-menu {
margin: 0;
padding: 0;
list-style: none;
.global-search-menu {
background: #26272e;
position: absolute;
left: 0;
@ -3285,17 +3295,48 @@ footer {
z-index: 900;
display: none;
overflow: auto;
}
.search.open .custom-dropdown-menu {
display: block;
}
.search .custom-dropdown-menu .divider {
.divider {
height: 1px;
background: #2f3238;
margin: 14px 0 17px;
}
}
.search.open .global-search-menu {
display: block;
}
.global-search-detail-link {
padding: 9px 15px 8px 0;
margin-bottom: 7px;
height: auto !important;
.nav-tab-icon {
width: 18px;
margin-left: 10px;
margin-right: 10px;
.icon {
width: 18px;
height: 14px;
}
}
.nav-tab-name {
.icon {
fill: currentColor;
margin: -2px 0 0 3px;
vertical-align: middle;
}
}
}
.global-search-result {
margin: 0;
padding: 0;
list-style: none;
}
.user-menu {
padding: 0;
@ -8218,6 +8259,10 @@ output {
}
}
.detail-search-header {
margin: 20px 0 32px;
}
/*
----------------

Binary file not shown.

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 59 KiB

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="18px" height="14px" viewBox="0 0 18 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 3.8.3 (29802) - http://www.bohemiancoding.com/sketch -->
<title>searchdetail</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="searchdetail" fill="#50E3C2">
<path d="M13.2097264,8.62000012 C12.3275246,8.61422004 11.614616,7.89207056 11.6200305,7.00952369 C11.6265279,6.13347943 12.3426852,5.42000008 13.2194725,5.42000008 L13.2299405,5.42000008 C13.6566027,5.42252886 14.0569144,5.59195763 14.3565165,5.89613465 C14.6564796,6.19958916 14.8203583,6.60311141 14.8178315,7.03047651 C14.8142219,7.45531282 14.6474554,7.85558377 14.3456875,8.15506447 C14.0446416,8.45490642 13.6439689,8.62000012 13.2201944,8.62000012 L13.2097264,8.62000012 M10.0000488,6.95269288 C9.99044948,8.7054343 11.3988803,10.1347405 13.1502196,10.1459486 C13.7533757,10.1459486 14.2994693,9.98903452 14.7677019,9.71363422 L16.694495,11.6430375 L16.7435581,11.690005 C16.8166194,11.7631248 16.9115459,11.7994179 17.0070056,11.7994179 C17.1024653,11.7994179 17.197925,11.7631248 17.2704531,11.690005 L17.8912079,11.0703543 C18.036264,10.9241146 18.036264,10.687676 17.8912079,10.5425037 L17.8426781,10.4928676 L15.9132185,8.56293066 C16.1825323,8.10072784 16.3371877,7.56593889 16.3409207,6.99325571 C16.3537198,5.24051429 14.9420892,3.81174183 13.1907499,3.79999995 C11.4298114,3.79999995 10.0117813,5.20688984 10.0000488,6.95269288 Z" id="search" opacity="0.5"></path>
<path d="M0,1 C0,0.44771525 0.448920205,0 1.00748397,0 L13.992516,0 C14.5489341,0 15,0.443864822 15,1 C15,1.55228475 14.5510798,2 13.992516,2 L1.00748397,2 C0.45106594,2 0,1.55613518 0,1 Z M0,5 C0,4.44771525 0.446311399,4 0.997544646,4 L8.00245535,4 C8.55338405,4 9,4.44386482 9,5 C9,5.55228475 8.5536886,6 8.00245535,6 L0.997544646,6 C0.446615951,6 0,5.55613518 0,5 Z M0,9 C0,8.44771525 0.446311399,8 0.997544646,8 L8.00245535,8 C8.55338405,8 9,8.44386482 9,9 C9,9.55228475 8.5536886,10 8.00245535,10 L0.997544646,10 C0.446615951,10 0,9.55613518 0,9 Z M0,13 C0,12.4477153 0.448920205,12 1.00748397,12 L13.992516,12 C14.5489341,12 15,12.4438648 15,13 C15,13.5522847 14.5510798,14 13.992516,14 L1.00748397,14 C0.45106594,14 0,13.5561352 0,13 Z" id="Combined-Shape"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -2297,7 +2297,7 @@ wait untill text in selector disabppears
# open ticket
#instance.find_element(partial_link_text: params[:number] } ).click
instance.execute_script("$(\"#global-search-result a:contains('#{params[:value]}') .nav-tab-icon\").click()")
instance.execute_script("$(\".js-global-search-result a:contains('#{params[:value]}') .nav-tab-icon\").click()")
sleep 1
number = instance.find_elements(css: '.active .ticketZoom-header .ticket-number')[0].text
if number !~ /#{params[:number]}/
@ -2332,7 +2332,7 @@ wait untill text in selector disabppears
# open ticket
#instance.find_element(partial_link_text: params[:title] } ).click
instance.execute_script("$(\"#global-search-result a:contains('#{params[:title]}') .nav-tab-icon\").click()")
instance.execute_script("$(\".js-global-search-result a:contains('#{params[:title]}') .nav-tab-icon\").click()")
sleep 1
title = instance.find_elements(css: '.active .ticketZoom-header .js-objectTitle')[0].text
if title !~ /#{params[:title]}/
@ -2420,7 +2420,7 @@ wait untill text in selector disabppears
element.send_keys(params[:value])
sleep 2
#instance.find_element(partial_link_text: params[:value] } ).click
instance.execute_script("$(\"#global-search-result a:contains('#{params[:value]}') .nav-tab-icon\").click()")
instance.execute_script("$(\".js-global-search-result a:contains('#{params[:value]}') .nav-tab-icon\").click()")
sleep 1
name = instance.find_elements(css: '.active h1')[0].text
if name !~ /#{params[:value]}/
@ -2453,7 +2453,7 @@ wait untill text in selector disabppears
element.send_keys(params[:value])
sleep 3
#instance.find_element(partial_link_text: params[:value]).click
instance.execute_script("$(\"#global-search-result a:contains('#{params[:value]}') .nav-tab-icon\").click()")
instance.execute_script("$(\".js-global-search-result a:contains('#{params[:value]}') .nav-tab-icon\").click()")
sleep 1
name = instance.find_elements(css: '.active h1')[0].text
if name !~ /#{params[:value]}/