search: style search detail, add detail link
This commit is contained in:
parent
d002da8a64
commit
613cc7ef20
10 changed files with 229 additions and 145 deletions
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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 |
13
public/assets/images/icons/searchdetail.svg
Normal file
13
public/assets/images/icons/searchdetail.svg
Normal 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 |
|
@ -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]}/
|
||||
|
|
Loading…
Reference in a new issue