1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-08-09 15:35:27 +02:00

search results UX

This commit is contained in:
Harvey Kandola 2016-07-01 18:53:56 -07:00
parent e173bccf52
commit d17351c6e4
10 changed files with 157 additions and 90 deletions

View file

@ -16,18 +16,28 @@ export default Ember.Component.extend({
resultPhrase: "", resultPhrase: "",
didReceiveAttrs() { didReceiveAttrs() {
let count = this.get('results').length; let results = this.get('results');
let self = this; let temp = _.groupBy(results, 'documentId');
let documents = [];
switch (count) { _.each(temp, function(document) {
case 0: documents.pushObject( {
self.set("resultPhrase", "No results."); doc: document[0],
break; ref: document
case 1: });
self.set("resultPhrase", "1 reference found"); });
break;
default: let phrase = 'Nothing found';
self.set("resultPhrase", `${count} references found`);
if (results.length > 0) {
let places = documents.length === 1 ? "place" : "places";
let references = results.length === 1 ? "secton" : "sections";
let i = results.length;
let j = documents.length;
phrase = `${i} ${references} in ${j} ${places}`;
} }
this.set('resultPhrase', phrase);
this.set('documents', documents);
} }
}); });

View file

@ -7,18 +7,16 @@ export default Ember.Controller.extend({
filter: "", filter: "",
results: [], results: [],
filterResults(filter) { onKeywordChange: function() {
Ember.run.debounce(this, this.fetch, 750);
}.observes('filter'),
fetch() {
this.audit.record('searched'); this.audit.record('searched');
let self = this; let self = this;
this.get('searchService').find(filter).then(function(response) { this.get('searchService').find(this.get('filter')).then(function(response) {
self.set('results', response); self.set('results', response);
}); });
},
actions: {
onFilter(filter) {
this.filterResults(filter);
}
} }
}); });

View file

@ -1,7 +1,17 @@
{{#header/page-navigation searchMode=true}} {{#layout/zone-container}}
{{header/search-box filter=filter onFilter=(action 'onFilter')}}
{{/header/page-navigation}}
{{#layout/page-container}} {{layout/zone-navigation}}
{{search/search-results results=results}}
{{/layout/page-container}} {{#layout/zone-header title=session.appMeta.title message=session.appMeta.message}}
{{/layout/zone-header}}
<div class="page-search">
<div class="input-control">
<label>Search</label>
<div class="tip">#tags, keywords, "some phrase", keyword AND keyword, keyword OR keyword</div>
{{focus-input class="input" type="text" value=filter placeholder='start typing...'}}
</div>
{{search/search-results results=results}}
</div>
{{/layout/zone-container}}

View file

@ -12,7 +12,6 @@
padding: 15px 40px 15px 40px; padding: 15px 40px 15px 40px;
.content { .content {
> .title { > .title {
padding-left: 15px; padding-left: 15px;
font-size: 1rem; font-size: 1rem;

View file

@ -1,44 +1,85 @@
.page-search {
margin: 30px 40px;
.search-results { .search-results {
.heading { margin-top: 50px;
font-size: 1.5rem;
color: $color-primary;
}
> .search-list { .heading {
@extend .cards-list; font-size: 1.2rem;
margin-top: 20px; color: $color-blue;
}
> .search-card { > .list {
@extend .content-card; margin-top: 20px;
width: 220px; list-style: none;
height: 200px;
cursor: pointer;
.folder { > .item {
font-size: 0.9rem; //width: 400px;
margin: 1.7rem 0 0 0; //float: left;
height: 1.2rem; cursor: pointer;
overflow: hidden; margin: 0 30px 30px 0;
color: $color-gray;
}
.tags { > .link {
font-size: 0.9rem; text-decoration: none;
height: 1.2rem; color: $color-off-black;
overflow: hidden;
color: $color-gray;
.tag { &:hover {
display: inline-block; color: $color-link;
margin-right: 5px; }
> .title {
display: inline-block;
font-size: 1.2rem;
}
> .folder {
display: inline-block;
font-size: 0.8rem;
color: $color-gray;
margin-left: 15px;
}
> .excerpt {
margin-top: 1rem;
font-size: 0.9rem;
margin-left: 20px;
}
> .chips {
margin-top: 1rem;
margin-left: 20px;
}
} }
}
a, a:hover { > .references {
text-decoration: none; margin-top: 1rem;
color: $color-off-black; margin-left: 20px;
}
} > .label {
font-size: 0.9rem;
color: $color-gray;
font-style: italic;
}
> .link {
font-size: 0.9rem;
color: $color-off-black;
&:hover {
color: $color-link;
text-decoration: underline;
}
&:after {
content: '·'
}
&:last-of-type:after {
content: ''
}
}
}
}
}
} }
} }

View file

@ -1,14 +1,21 @@
<div class="search-results"> <div class="search-results">
<h2 class="heading">{{resultPhrase}}</h2> <h2 class="heading">{{resultPhrase}}</h2>
<ul class="search-list"> <ul class="list">
{{#each results key="id" as |result index|}} {{#each documents key="doc.id" as |result index|}}
<li class="search-card"> <li class="item">
<a href="s/{{result.folderId}}/{{result.folderSlug}}/d/{{ result.documentId }}/{{result.documentSlug}}?page={{ result.id }}"> <a class="link" href="s/{{result.doc.folderId}}/{{result.doc.folderSlug}}/d/{{ result.doc.documentId }}/{{result.doc.documentSlug}}?page={{ result.doc.id }}">
<div class="title">{{ result.documentTitle }}</div> <div class="title">{{ result.doc.documentTitle }}</div><div class="folder">{{ result.doc.folderName }}</div>
<div class="snippet">{{ result.pageTitle }}</div> <div class="excerpt">{{ result.doc.documentExcerpt }}</div>
<div class="folder">{{ result.folderName }}</div> <div class="chips">{{search/tag-list documentTags=result.doc.documentTags}}</div>
<div class="tags">{{search/tag-list documentTags=result.documentTags}}</div>
</a> </a>
<div class="references">
<span class="label">referenced &raquo;</span>
{{#each result.ref as |ref index|}}
<a class="link" href="s/{{result.doc.folderId}}/{{result.doc.folderSlug}}/d/{{ result.doc.documentId }}/{{result.doc.documentSlug}}?page={{ ref.id }}">
{{ref.pageTitle}}
</a>
{{/each}}
</div>
</li> </li>
{{/each}} {{/each}}
</ul> </ul>

View file

@ -1,5 +1,7 @@
<div class="tags"> <div class="chips">
{{#each tagz as |tg|}} {{#each tagz as |tg|}}
<div class="tag">#{{tg}}</div> <div class="chip">
<span class="chip-text">#{{tg}}</span>
</div>
{{/each}} {{/each}}
</div> </div>

View file

@ -18,7 +18,6 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"strings"
"github.com/documize/community/documize/api/entity" "github.com/documize/community/documize/api/entity"
"github.com/documize/community/documize/api/plugins" "github.com/documize/community/documize/api/plugins"
@ -54,6 +53,10 @@ func SearchDocuments(w http.ResponseWriter, r *http.Request) {
results[key] = result results[key] = result
} }
if len(results) == 0 {
results = []entity.DocumentSearch{}
}
data, err := json.Marshal(results) data, err := json.Marshal(results)
if err != nil { if err != nil {
@ -61,10 +64,6 @@ func SearchDocuments(w http.ResponseWriter, r *http.Request) {
return return
} }
if strings.ToLower(string(data)) == "null" {
data = []byte("[ ]")
}
writeSuccessBytes(w, data) writeSuccessBytes(w, data)
} }

View file

@ -275,15 +275,16 @@ type Search struct {
// DocumentSearch represents 'presentable' search results. // DocumentSearch represents 'presentable' search results.
type DocumentSearch struct { type DocumentSearch struct {
ID string `json:"id"` ID string `json:"id"`
DocumentID string `json:"documentId"` DocumentID string `json:"documentId"`
DocumentTitle string `json:"documentTitle"` DocumentTitle string `json:"documentTitle"`
DocumentSlug string `json:"documentSlug"` DocumentSlug string `json:"documentSlug"`
Tags string `json:"documentTags"` DocumentExcerpt string `json:"documentExcerpt"`
PageTitle string `json:"pageTitle"` Tags string `json:"documentTags"`
LabelID string `json:"folderId"` PageTitle string `json:"pageTitle"`
LabelName string `json:"folderName"` LabelID string `json:"folderId"`
FolderSlug string `json:"folderSlug"` LabelName string `json:"folderName"`
FolderSlug string `json:"folderSlug"`
} }
// SiteMeta holds information associated with an Organization. // SiteMeta holds information associated with an Organization.

View file

@ -244,7 +244,7 @@ func (p *Persister) SearchDocument(keywords string) (results []entity.DocumentSe
} }
sql := `SELECT search.id, documentid, pagetitle, document.labelid, document.title as documenttitle, document.tags, sql := `SELECT search.id, documentid, pagetitle, document.labelid, document.title as documenttitle, document.tags,
COALESCE(label.label,'Unknown') AS labelname COALESCE(label.label,'Unknown') AS labelname, document.excerpt as documentexcerpt
FROM search, document LEFT JOIN label ON label.orgid=document.orgid AND label.refid = document.labelid FROM search, document LEFT JOIN label ON label.orgid=document.orgid AND label.refid = document.labelid
WHERE search.documentid = document.refid AND search.orgid=? AND document.template=0 ` + tagQuery + WHERE search.documentid = document.refid AND search.orgid=? AND document.template=0 ` + tagQuery +
`AND document.labelid IN `AND document.labelid IN