FEATURE: revamp full-page-search UI (#5703)

This is the first iteration of this revamp, a following iteration will focus on improving the controls in the advanced search sidebar.
This commit is contained in:
Joffrey JAFFEUX 2018-04-09 17:51:09 +02:00 committed by Kris
parent 41150fc0cd
commit bd7100a062
16 changed files with 405 additions and 328 deletions

View File

@ -174,7 +174,7 @@ export default Ember.Controller.extend({
@computed('expanded')
searchAdvancedIcon(expanded) {
return iconHTML(expanded ? "caret-down" : "caret-right");
return iconHTML(expanded ? "caret-down fa-fw" : "caret-right fa-fw");
},
@computed('page')

View File

@ -1,163 +1,188 @@
{{#d-section pageClass="search" class="search-container"}}
{{scroll-tracker name="full-page-search" tag=searchTerm}}
<div class="search row clearfix">
<div class="search-bar">
{{search-text-field value=searchTerm class="full-page-search input-xxlarge search no-blur" action="search" hasAutofocus=hasAutofocus}}
{{d-button action="search" icon="search" class="btn-primary" disabled=searching}}
</div>
<div class='search-advanced'>
<button class="search-advanced-btn btn" {{action "toggleAdvancedSearch"}}>
{{{searchAdvancedIcon}}}
{{i18n "search.advanced.title"}}
</button>
{{scroll-tracker name="full-page-search" tag=searchTerm class="hidden"}}
{{#if expanded}}
{{search-advanced-options searchTerm=searchTerm isExpanded=expanded}}
<div class="search-advanced">
{{#unless site.mobileView}}
<div class="search-bar">
{{search-text-field value=searchTerm class="full-page-search search no-blur search-query" action="search" hasAutofocus=hasAutofocus}}
{{d-button action="search" icon="search" class="btn-primary search-cta" disabled=searching}}
</div>
{{/unless}}
<div class="search-notice">
{{#if invalidSearch}}
<div class="fps-invalid">
{{i18n "search.too_short"}}
</div>
{{/if}}
</div>
{{#if hasResults}}
{{create-topic-button canCreateTopic=canCreateTopic action=(action "createTopic" searchTerm)}}
<div class='search-title'>
{{#if hasResults}}
{{create-topic-button canCreateTopic=canCreateTopic action=(action "createTopic" searchTerm)}}
{{/if}}
{{#if canBulkSelect}}
{{d-button icon="list" class="bulk-select" title="topics.bulk.toggle" action="toggleBulkSelect"}}
{{bulk-select-button selected=selected action="search"}}
{{/if}}
{{#if bulkSelectEnabled}}
<div class='fps-select'>
<a {{action "selectAll"}}>{{i18n "search.select_all"}}</a>
<a {{action "clearAll"}}>{{i18n "search.clear_all"}}</a>
</div>
{{/if}}
</div>
<div class='search-info'>
<div class='result-count'>
{{{resultCountLabel}}}
</div>
<div class='sort-by'>
<span class='desc'>
{{i18n "search.sort_by"}}
</span>
{{combo-box value=sortOrder content=sortOrders castInteger=true}}
</div>
</div>
{{/if}}
{{#if canBulkSelect}}
{{d-button icon="list" class="bulk-select" title="topics.bulk.toggle" action="toggleBulkSelect"}}
{{bulk-select-button selected=selected action="search"}}
{{/if}}
<div class="search-results">
{{#load-more selector=".fps-result" action="loadMore"}}
{{#each model.posts as |result|}}
<div class='fps-result'>
<div class='author'>
<a href={{result.userPath}} data-user-card="{{unbound result.username}}">
{{avatar result imageSize="large"}}
</a>
</div>
<div class='fps-topic'>
<div class='topic'>
{{#if bulkSelectEnabled}}
{{track-selected selectedList=selected selectedId=result.topic}}
{{/if}}
<a class='search-link' href='{{unbound result.url}}' {{action "logClick" result.topic_id}}>
{{topic-status topic=result.topic disableActions=true}}<span class='topic-title'>{{#highlight-text highlight=q}}{{{unbound result.topic.fancyTitle}}}{{/highlight-text}}</span>
</a>
<div class='search-category'>
{{#if result.topic.category.parentCategory}}
{{category-link result.topic.category.parentCategory}}
{{/if}}
{{category-link result.topic.category hideParent=true}}
{{#each result.topic.tags as |tag|}}
{{discourse-tag tag}}
{{/each}}
{{plugin-outlet name="full-page-search-category" args=(hash result=result)}}
</div>
</div>
<div class='blurb container'>
<span class='date'>
{{format-age result.created_at}}
{{#if result.blurb}}
-
{{/if}}
</span>
{{#if result.blurb}}
{{#highlight-text highlight=highlightQuery}}
{{{unbound result.blurb}}}
{{/highlight-text}}
{{/if}}
</div>
{{#if showLikeCount}}
{{#if result.like_count}}
<span class='like-count'>
{{result.like_count}} {{d-icon "heart"}}
</span>
{{/if}}
{{/if}}
</div>
</div>
{{/each}}
{{#conditional-loading-spinner condition=loading }}
{{#unless hasResults}}
{{#if searchActive}}
<h3>{{i18n "search.no_results"}}</h3>
{{#if showSuggestion}}
<div class="no-results-suggestion">
{{i18n "search.cant_find"}}
{{#if canCreateTopic}}
<a href {{action "createTopic" searchTerm}}>{{i18n "search.start_new_topic"}}</a>
{{#unless siteSettings.login_required}}
{{i18n "search.or_search_google"}}
{{/unless}}
{{else}}
{{i18n "search.search_google"}}
{{/if}}
</div>
{{google-search searchTerm=searchTerm}}
{{/if}}
{{/if}}
{{/unless}}
{{#if hasResults}}
{{#unless loading}}
<h3 class="search-footer">
{{#if model.grouped_search_result.more_full_page_results}}
{{#if isLastPage }}
{{i18n "search.more_results"}}
{{/if}}
{{else}}
{{i18n "search.no_more_results"}}
{{/if}}
</h3>
{{/unless}}
{{/if}}
{{/conditional-loading-spinner}}
{{/load-more}}
</div>
</div>
{{#if bulkSelectEnabled}}
<div class='fps-select'>
<a {{action "selectAll"}}>{{i18n "search.select_all"}}</a>
<a {{action "clearAll"}}>{{i18n "search.clear_all"}}</a>
</div>
{{/if}}
{{#if invalidSearch}}
<div class='fps-invalid'>
{{i18n "search.too_short"}}
</div>
{{/if}}
{{#if context}}
<div class='fps-search-context'>
<label>
{{input type="checkbox" name="searchContext" checked=searchContextEnabled}} {{searchContextDescription}}
</label>
</div>
{{/if}}
{{#if hasResults}}
<div class='search-title clearfix'>
<div class='result-count'>
<span>
{{{resultCountLabel}}}
</span>
<div class="search-advanced-sidebar">
{{#if site.mobileView}}
<div class="search-bar">
{{search-text-field value=searchTerm class="full-page-search search no-blur search-query" action="search" hasAutofocus=hasAutofocus}}
{{d-button action="search" icon="search" class="btn-primary search-cta" disabled=searching}}
</div>
<div class='sort-by'>
<span class='desc'>
{{i18n "search.sort_by"}}
</span>
{{combo-box value=sortOrder content=sortOrders castInteger=true}}
</div>
</div>
{{/if}}
{{/if}}
{{#load-more selector=".fps-result" action="loadMore"}}
{{#each model.posts as |result|}}
<div class='fps-result'>
<div class='author'>
<a href={{result.userPath}} data-user-card="{{unbound result.username}}">
{{avatar result imageSize="large"}}
</a>
{{#if site.mobileView}}
<button class="search-advanced-title btn" {{action "toggleAdvancedSearch"}}>
{{{searchAdvancedIcon}}} {{i18n "search.advanced.title"}}
</button>
{{else}}
<span class="search-advanced-title">
{{i18n "search.advanced.title"}}
</span>
{{/if}}
{{#if site.mobileView}}
{{#if expanded}}
<div class="search-advanced-filters">
{{search-advanced-options searchTerm=searchTerm isExpanded=expanded}}
</div>
<div class='fps-topic'>
<div class='topic'>
{{#if bulkSelectEnabled}}
{{track-selected selectedList=selected selectedId=result.topic}}
{{/if}}
<a class='search-link' href='{{unbound result.url}}' {{action "logClick" result.topic_id}}>
{{topic-status topic=result.topic disableActions=true}}<span class='topic-title'>{{#highlight-text highlight=q}}{{{unbound result.topic.fancyTitle}}}{{/highlight-text}}</span>
</a>
<div class='search-category'>
{{#if result.topic.category.parentCategory}}
{{category-link result.topic.category.parentCategory}}
{{/if}}
{{category-link result.topic.category hideParent=true}}
{{#each result.topic.tags as |tag|}}
{{discourse-tag tag}}
{{/each}}
{{plugin-outlet name="full-page-search-category" args=(hash result=result)}}
</div>
</div>
<div class='blurb container'>
<span class='date'>
{{format-age result.created_at}}
{{#if result.blurb}}
-
{{/if}}
</span>
{{#if result.blurb}}
{{#highlight-text highlight=highlightQuery}}
{{{unbound result.blurb}}}
{{/highlight-text}}
{{/if}}
</div>
{{#if showLikeCount}}
{{#if result.like_count}}
<span class='like-count'>
{{result.like_count}} {{d-icon "heart"}}
</span>
{{/if}}
{{/if}}
</div>
</div>
{{/each}}
{{#conditional-loading-spinner condition=loading }}
{{#unless hasResults}}
{{#if searchActive}}
<h3>{{i18n "search.no_results"}}</h3>
{{#if showSuggestion}}
<div class="no-results-suggestion">
{{i18n "search.cant_find"}}
{{#if canCreateTopic}}
<a href {{action "createTopic" searchTerm}}>{{i18n "search.start_new_topic"}}</a>
{{#unless siteSettings.login_required}}
{{i18n "search.or_search_google"}}
{{/unless}}
{{else}}
{{i18n "search.search_google"}}
{{/if}}
</div>
{{google-search searchTerm=searchTerm}}
{{/if}}
{{/if}}
{{/unless}}
{{#if hasResults}}
{{#unless loading}}
<h3 class="search-footer">
{{#if model.grouped_search_result.more_full_page_results}}
{{#if isLastPage }}
{{i18n "search.more_results"}}
{{/if}}
{{else}}
{{i18n "search.no_more_results"}}
{{/if}}
</h3>
{{/unless}}
{{/if}}
{{/conditional-loading-spinner}}
{{/load-more}}
{{else}}
<div class="search-advanced-filters">
{{search-advanced-options searchTerm=searchTerm isExpanded=true}}
{{d-button
label="submit"
action="search"
icon="search"
class="btn-primary search-cta"
disabled=searching}}
</div>
{{/if}}
</div>
{{/d-section}}

View File

@ -1,9 +1,182 @@
.search-container {
display: flex;
justify-content: space-between;
.search-bar {
display: flex;
justify-content: space-between;
align-items: center;
justify-content: space-between;
margin-bottom: 1em;
.search-query {
flex: 1;
margin: 0 .5em 0 0;
}
.search-cta {
padding-bottom: 6.5px;
padding-top: 6.5px;
}
}
.search-advanced {
width: 70%;
@include small-width { width: 65%; }
.search-actions,
.search-notice,
.search-results,
.search-title,
.search-bar {
margin-bottom: 1em;
}
.search-info {
display: flex;
flex-wrap: wrap;
border-bottom: 3px solid $primary-low;
padding-bottom: .5em;
margin-bottom: 1em;
flex-direction: row;
align-items: center;
.result-count {
display: flex;
.term {
font-weight: bold;
}
// spans can be in different orders depending of locale
span + span {
margin-left: .25em;
}
}
.sort-by {
display: flex;
margin-left: auto;
align-items: center;
.desc {
margin-right: .5em;
}
.combo-box {
min-width: 150px;
}
}
}
.search-title {
display: flex;
justify-content: flex-start;
align-items: center;
.bulk-select {
margin-left: .5em;
}
.fps-select a {
margin-left: .5em;
font-size: $font-down-1;
&:hover {
text-decoration: underline;
}
}
}
.search-notice {
.fps-invalid {
padding: .5em;
background-color: $danger-low;
border: 1px solid $danger-medium;
color: $danger;
}
}
}
.search-advanced-sidebar {
width: 30%;
@include small-width { width: 35%; }
margin-left: 1em;
display: flex;
flex-direction: column;
#search-min-post-count,
.date-picker,
.combo-box,
.ac-wrap,
.control-group,
.date-picker-wrapper,
.search-advanced-category-chooser {
box-sizing: border-box;
width: 100%;
min-width: 100%;
input, .item {
padding-left: 4px; // temporarily normalizing input padding for this section
}
}
.date-picker-wrapper {
margin-top: .5em;
}
.date-picker {
box-sizing: border-box;
text-align: left;
padding: 4px;
margin-bottom: 0;
}
.search-advanced-title {
background: $primary-low;
padding: .358em 1em;
@include small-width { padding: .358em .5em; }
font-weight: 700;
text-align: left;
font-weight: bold;
&.btn {
background: $primary-low;
}
.d-icon {
margin: 0;
}
}
.search-advanced-filters {
background: $primary-very-low;
padding: 1em;
.control-group {
margin-bottom: 15px;
}
section.field {
margin-top: 5px;
}
@include small-width {
padding: .75em .5em;
.ac-wrap, .choices, .select-kit.multi-select { // overriding inline width from JS
width: 100% !important;
}
.select-kit {
min-width: unset;
}
}
}
}
}
.fps-invalid {
margin-bottom: 1em;
}
.fps-result {
display: flex;
.author {
display: inline-block;
vertical-align: top;
@ -71,42 +244,6 @@
display: inline-block;
}
.fps-select {
margin-top: -15px;
margin-bottom: 15px;
a:hover {
color: $secondary;
background-color: $tertiary;
}
a {
margin-right: 15px;
font-size: $font-down-1;
padding: 2px 5px;
}
}
.search.row {
margin-bottom: 15px;
.input-xxlarge {
width: 100%;
}
.search-bar {
display: flex;
margin-bottom: 10px;
max-width: 780px;
input {
height: 22px;
padding-left: 6px;
margin: 0 5px 0 0;
}
}
.new-topic-btn {
float:right;
}
}
.no-results-suggestion {
margin-top: 30px;
}
@ -118,96 +255,6 @@
float: left;
}
.search-title {
position: relative;
margin: 10px 0 15px;
max-width: 780px;
border-bottom: 3px solid $primary-low;
width: 100%;
.term {
font-weight: bold;
}
.result-count {
float: left;
margin-bottom: 4px;
span {
line-height: $line-height-large;
height: 28px;
display: inline-block;
}
}
.sort-by {
float: right;
margin-bottom: 4px;
.desc {
margin-right: 5px;
}
select {
margin-bottom: 0;
width: auto;
min-width: 150px;
}
}
}
.google-search-form {
margin-top: 2em;
}
.search-advanced {
display: flex;
flex-wrap: wrap;
margin-bottom: 20px;
max-width: 780px;
.search-advanced-options {
border: 1px solid $primary-low;
padding: 0 20px;
width: 100%;
.date-picker-wrapper {
vertical-align: top;
}
@media screen and (max-width: 715px) {
padding: 0 10px;
#postTime {
margin: 0 0 5px 0;
}
}
}
.search-advanced-btn {
flex: 1 1 100%;
width: 100%;
text-align: left;
font-weight: bold;
}
.tag-chooser {
width: 70%;
}
.container {
display: flex;
flex: 1 1 100%;
padding: 15px 0 10px 0;
.all-tags {
margin-bottom: 0;
}
@media screen and (max-width: 600px) {
flex-wrap: wrap;
}
&:not(:first-of-type) {
border-top: 1px solid $primary-low;
}
.control-group {
flex: 1 1 100%;
@media screen and (max-width: 600px) {
margin: 0;
&:nth-of-type(2) {
margin-top: 5px;
}
}
}
}
}

View File

@ -65,7 +65,6 @@
.choices {
margin: 0;
padding: 2.5px;
box-sizing: border-box;
display: inline-flex;
justify-content: flex-start;

View File

@ -194,6 +194,10 @@
&.is-selected.is-highlighted {
background: $tertiary-low;
}
.discourse-tag, .discourse-tag-count {
color: $primary;
}
}
.select-kit-collection {

View File

@ -1,43 +1,45 @@
.search button.btn-primary, .search button.btn {
float: none;
}
.search-container {
flex-direction: column;
margin-top: .5em;
.search-advanced {
.search-advanced-options {
.control-group {
margin-bottom: 10px;
.controls {
input:not([type="checkbox"]),select {
width: 75%;
.search-advanced {
order: 1;
width: 100%;
.search-info {
flex-direction: column;
align-items: left;
justify-content: center;
.sort-by {
display: flex;
align-items: center;
margin-top: .5em;
margin-left: 0;
width: 100%;
.select-kit {
flex: 1 1 auto;
}
}
}
}
}
.search-title {
.sort-by {
display: flex;
.search-notice {
margin-top: 1em;
}
.search-advanced-sidebar {
order: 0;
width: 100%;
align-items: center;
.select-kit {
flex: 1 1 auto;
margin: 0;
.tag-chooser {
width: 100%;
}
}
}
.search.row {
margin-top: 10px;
}
.search.row input.search {
height: 25px;
}
.fps-search-context {
margin-bottom: 15px;
}
.fps-topic {
max-width: 75%;
}

View File

@ -1328,9 +1328,9 @@ cs:
clear_all: "Vymazat vše"
too_short: "Hledaný výraz je příliš krátký."
result_count:
one: "1 výsledek pro <span class='term'>\"{{term}}\"</span>"
few: "{{count}}{{plus}} výsledky pro <span class='term'>\"{{term}}\"</span>"
other: "{{count}}{{plus}} výsledků pro <span class='term'>\"{{term}}\"</span>"
one: "<span>1 výsledek pro</span><span class='term'>\"{{term}}\"</span>"
few: "<span>{{count}}{{plus}} výsledky pro</span><span class='term'>\"{{term}}\"</span>"
other: "<span>{{count}}{{plus}} výsledků pro</span><span class='term'>\"{{term}}\"</span>"
title: "vyhledávat témata, příspěvky, uživatele nebo kategorie"
no_results: "Nenalezeny žádné výsledky."
no_more_results: "Nenalezeny žádné další výsledky."

View File

@ -1288,8 +1288,8 @@ de:
clear_all: "Auswahl aufheben"
too_short: "Der Suchbegriff ist zu kurz."
result_count:
one: "1 Ergebnis für <span class='term'>{{term}}</span>"
other: "{{count}}{{plus}} Ergebnisse für <span class='term'>{{term}}</span>"
one: "<span>1 Ergebnis für</span><span class='term'>{{term}}</span>"
other: "<span>{{count}}{{plus}} Ergebnisse für</span><span class='term'>{{term}}</span>"
title: "suche nach Themen, Beiträgen, Benutzern oder Kategorien"
no_results: "Keine Ergebnisse gefunden."
no_more_results: "Es wurde keine weiteren Ergebnisse gefunden."

View File

@ -1464,8 +1464,8 @@ en:
clear_all: "Clear All"
too_short: "Your search term is too short."
result_count:
one: "1 result for <span class='term'>{{term}}</span>"
other: "{{count}}{{plus}} results for <span class='term'>{{term}}</span>"
one: "<span>1 result for</span><span class='term'>{{term}}</span>"
other: "<span>{{count}}{{plus}} results for</span><span class='term'>{{term}}</span>"
title: "search topics, posts, users, or categories"
no_results: "No results found."
no_more_results: "No more results found."

View File

@ -1342,8 +1342,8 @@ es:
clear_all: "Limpiar todo"
too_short: "El término de búsqueda es demasiado corto."
result_count:
one: "1 resultado para <span class='term'>{{term}}</span>"
other: "{{count}}{{plus}} resultados para <span class='term'>{{term}}</span>"
one: "<span>1 resultado para</span><span class='term'>{{term}}</span>"
other: "<span>{{count}}{{plus}} resultados para</span><span class='term'>{{term}}</span>"
title: "buscar temas, posts, usuarios o categorías"
no_results: "No se ha encontrado ningún resultado."
no_more_results: "No se encontraron más resultados."

View File

@ -1292,8 +1292,8 @@ fi:
clear_all: "Tyhjennä kaikki"
too_short: "Hakusana on liian lyhyt."
result_count:
one: "Yksi tulos haulle <span class='term'>{{term}}</span>"
other: "{{count}}{{plus}} tulosta haulle <span class='term'>{{term}}</span>"
one: "<span>Yksi tulos haulle</span><span class='term'>{{term}}</span>"
other: "<span>{{count}}{{plus}} tulosta haulle</span><span class='term'>{{term}}</span>"
title: "etsi ketjuja, viestejä, käyttäjiä tai alueita"
no_results: "Ei tuloksia."
no_more_results: "Enempää tuloksia ei löytynyt."

View File

@ -1345,8 +1345,8 @@ fr:
clear_all: "Tout désélectionner"
too_short: "Votre terme de recherche est trop court."
result_count:
one: "1 résultat pour <span class='term'>{{term}}</span>"
other: "{{count}}{{plus}} résultats pour <span class='term'>{{term}}</span>"
one: "<span>1 résultat pour</span><span class='term'>{{term}}</span>"
other: "<span>{{count}}{{plus}} résultats pour</span><span class='term'>{{term}}</span>"
title: "rechercher des sujets, messages, utilisateurs ou catégories"
no_results: "Aucun résultat."
no_more_results: "Aucun résultat supplémentaire."

View File

@ -1192,8 +1192,8 @@ it:
clear_all: "Cancella Tutto"
too_short: "La tua chiave di ricerca è troppo corta."
result_count:
one: "1 risultato per <span class='term'>{{term}}</span>"
other: "{{count}}{{plus}} risultati per <span class='term'>{{term}}</span>"
one: "<span>1 risultato per</span><span class='term'>{{term}}</span>"
other: "<span>{{count}}{{plus}} risultati per</span><span class='term'>{{term}}</span>"
title: "cerca argomenti, messaggi, utenti o categorie"
no_results: "Nessun risultato trovato."
no_more_results: "Nessun altro risultato trovato."

View File

@ -1316,8 +1316,8 @@ nb_NO:
clear_all: "Fjern Alle"
too_short: "Din søketekst er for kort."
result_count:
one: "1 resultat for <span class='term'>{{term}}</span>"
other: "{{count}}{{plus}} resultater for <span class='term'>{{term}}</span>"
one: "<span>1 resultat for</span><span class='term'>{{term}}</span>"
other: "<span>{{count}}{{plus}} resultater for</span><span class='term'>{{term}}</span>"
title: "søk etter tråder, innlegg, brukere eller kategorier"
no_results: "Ingen resultater funnet."
no_more_results: "Ingen flere resultater funnet."

View File

@ -889,10 +889,10 @@ sl:
clear_all: "Počisti vse"
too_short: "Niz za iskanje je prekratek"
result_count:
one: "1 zadetek za <span class='term'>{{term}}</span>"
two: "{{count}}{{plus}} zadetka za <span class='term'>{{term}}</span>"
few: "{{count}}{{plus}} zadetkov za <span class='term'>{{term}}</span>"
other: "{{count}}{{plus}} zadetkov za <span class='term'>{{term}}</span>"
one: "<span>1 zadetek za</span><span class='term'>{{term}}</span>"
two: "<span>{{count}}{{plus}} zadetka za</span><span class='term'>{{term}}</span>"
few: "<span>{{count}}{{plus}} zadetkov za</span><span class='term'>{{term}}</span>"
other: "<span>{{count}}{{plus}} zadetkov za</span><span class='term'>{{term}}</span>"
title: "išči po temah, objavah, uporabnikih ali kategorijah"
no_results: "Iskanje nima zadetkov."
no_more_results: "Ni več zadetkov iskanja."

View File

@ -1189,8 +1189,8 @@ tr_TR:
clear_all: "Tümünü Temizle"
too_short: "Aradığın terim çok kısa."
result_count:
one: "<span class='term'>{{term}}</span> için {{count}}{{plus}} sonuç"
other: "<span class='term'>{{term}}</span> için {{count}}{{plus}} sonuç"
one: "<span class='term'>{{term}}</span><span>için {{count}}{{plus}} sonuç</span>"
other: "<span class='term'>{{term}}</span><span>için {{count}}{{plus}} sonuç</span>"
title: "konu, gönderi, kullanıcı veya kategori ara"
no_results: "Hiç bir sonuç bulunamadı."
no_more_results: "Başka sonuç yok."