diff --git a/app/app/components/search/search-results.js b/app/app/components/search/search-results.js index dca722aa..8e1c56c0 100644 --- a/app/app/components/search/search-results.js +++ b/app/app/components/search/search-results.js @@ -1,11 +1,11 @@ // Copyright 2016 Documize Inc. . All rights reserved. // -// This software (Documize Community Edition) is licensed under +// This software (Documize Community Edition) is licensed under // GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html // // You can operate outside the AGPL restrictions by purchasing // Documize Enterprise Edition and obtaining a commercial license -// by contacting . +// by contacting . // // https://documize.com @@ -16,18 +16,28 @@ export default Ember.Component.extend({ resultPhrase: "", didReceiveAttrs() { - let count = this.get('results').length; - let self = this; + let results = this.get('results'); + let temp = _.groupBy(results, 'documentId'); + let documents = []; - switch (count) { - case 0: - self.set("resultPhrase", "No results."); - break; - case 1: - self.set("resultPhrase", "1 reference found"); - break; - default: - self.set("resultPhrase", `${count} references found`); + _.each(temp, function(document) { + documents.pushObject( { + doc: document[0], + ref: document + }); + }); + + let phrase = 'Nothing 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); } -}); \ No newline at end of file +}); diff --git a/app/app/pods/search/controller.js b/app/app/pods/search/controller.js index 7437690e..8d992b6b 100644 --- a/app/app/pods/search/controller.js +++ b/app/app/pods/search/controller.js @@ -7,18 +7,16 @@ export default Ember.Controller.extend({ filter: "", results: [], - filterResults(filter) { + onKeywordChange: function() { + Ember.run.debounce(this, this.fetch, 750); + }.observes('filter'), + + fetch() { this.audit.record('searched'); 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); }); - }, - - actions: { - onFilter(filter) { - this.filterResults(filter); - } } }); diff --git a/app/app/pods/search/template.hbs b/app/app/pods/search/template.hbs index 18790d63..ce1b44b4 100644 --- a/app/app/pods/search/template.hbs +++ b/app/app/pods/search/template.hbs @@ -1,7 +1,17 @@ -{{#header/page-navigation searchMode=true}} - {{header/search-box filter=filter onFilter=(action 'onFilter')}} -{{/header/page-navigation}} +{{#layout/zone-container}} -{{#layout/page-container}} - {{search/search-results results=results}} -{{/layout/page-container}} + {{layout/zone-navigation}} + + {{#layout/zone-header title=session.appMeta.title message=session.appMeta.message}} + {{/layout/zone-header}} + + + +{{/layout/zone-container}} diff --git a/app/app/styles/view/layout.scss b/app/app/styles/view/layout.scss index 1c15e8f7..db5b9aaf 100644 --- a/app/app/styles/view/layout.scss +++ b/app/app/styles/view/layout.scss @@ -12,7 +12,6 @@ padding: 15px 40px 15px 40px; .content { - > .title { padding-left: 15px; font-size: 1rem; diff --git a/app/app/styles/view/page-search.scss b/app/app/styles/view/page-search.scss index 5c396ef1..11360dcb 100644 --- a/app/app/styles/view/page-search.scss +++ b/app/app/styles/view/page-search.scss @@ -1,44 +1,85 @@ +.page-search { + margin: 30px 40px; -.search-results { - .heading { - font-size: 1.5rem; - color: $color-primary; - } + .search-results { + margin-top: 50px; - > .search-list { - @extend .cards-list; - margin-top: 20px; + .heading { + font-size: 1.2rem; + color: $color-blue; + } - > .search-card { - @extend .content-card; - width: 220px; - height: 200px; - cursor: pointer; + > .list { + margin-top: 20px; + list-style: none; - .folder { - font-size: 0.9rem; - margin: 1.7rem 0 0 0; - height: 1.2rem; - overflow: hidden; - color: $color-gray; - } + > .item { + //width: 400px; + //float: left; + cursor: pointer; + margin: 0 30px 30px 0; - .tags { - font-size: 0.9rem; - height: 1.2rem; - overflow: hidden; - color: $color-gray; + > .link { + text-decoration: none; + color: $color-off-black; - .tag { - display: inline-block; - margin-right: 5px; + &:hover { + color: $color-link; + } + + > .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 { - text-decoration: none; - color: $color-off-black; - } - } + > .references { + margin-top: 1rem; + 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: '' + } + } + } + } + } } } diff --git a/app/app/templates/components/search/search-results.hbs b/app/app/templates/components/search/search-results.hbs index 5ed81eea..df82b3a1 100644 --- a/app/app/templates/components/search/search-results.hbs +++ b/app/app/templates/components/search/search-results.hbs @@ -1,14 +1,21 @@

{{resultPhrase}}

-
    - {{#each results key="id" as |result index|}} -
  • - -
    {{ result.documentTitle }}
    -
    {{ result.pageTitle }}
    -
    {{ result.folderName }}
    -
    {{search/tag-list documentTags=result.documentTags}}
    +
    diff --git a/app/app/templates/components/search/tag-list.hbs b/app/app/templates/components/search/tag-list.hbs index 3bbf4a14..c5f82d78 100644 --- a/app/app/templates/components/search/tag-list.hbs +++ b/app/app/templates/components/search/tag-list.hbs @@ -1,5 +1,7 @@ -
    +
    {{#each tagz as |tg|}} -
    #{{tg}}
    +
    + #{{tg}} +
    {{/each}}
    diff --git a/documize/api/endpoint/document_endpoint.go b/documize/api/endpoint/document_endpoint.go index 858a07be..cb6c93fc 100644 --- a/documize/api/endpoint/document_endpoint.go +++ b/documize/api/endpoint/document_endpoint.go @@ -1,11 +1,11 @@ // Copyright 2016 Documize Inc. . All rights reserved. // -// This software (Documize Community Edition) is licensed under +// This software (Documize Community Edition) is licensed under // GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html // // You can operate outside the AGPL restrictions by purchasing // Documize Enterprise Edition and obtaining a commercial license -// by contacting . +// by contacting . // // https://documize.com @@ -18,7 +18,6 @@ import ( "io/ioutil" "net/http" "net/url" - "strings" "github.com/documize/community/documize/api/entity" "github.com/documize/community/documize/api/plugins" @@ -54,6 +53,10 @@ func SearchDocuments(w http.ResponseWriter, r *http.Request) { results[key] = result } + if len(results) == 0 { + results = []entity.DocumentSearch{} + } + data, err := json.Marshal(results) if err != nil { @@ -61,10 +64,6 @@ func SearchDocuments(w http.ResponseWriter, r *http.Request) { return } - if strings.ToLower(string(data)) == "null" { - data = []byte("[ ]") - } - writeSuccessBytes(w, data) } diff --git a/documize/api/entity/objects.go b/documize/api/entity/objects.go index ee8622eb..88cd01c3 100644 --- a/documize/api/entity/objects.go +++ b/documize/api/entity/objects.go @@ -275,15 +275,16 @@ type Search struct { // DocumentSearch represents 'presentable' search results. type DocumentSearch struct { - ID string `json:"id"` - DocumentID string `json:"documentId"` - DocumentTitle string `json:"documentTitle"` - DocumentSlug string `json:"documentSlug"` - Tags string `json:"documentTags"` - PageTitle string `json:"pageTitle"` - LabelID string `json:"folderId"` - LabelName string `json:"folderName"` - FolderSlug string `json:"folderSlug"` + ID string `json:"id"` + DocumentID string `json:"documentId"` + DocumentTitle string `json:"documentTitle"` + DocumentSlug string `json:"documentSlug"` + DocumentExcerpt string `json:"documentExcerpt"` + Tags string `json:"documentTags"` + PageTitle string `json:"pageTitle"` + LabelID string `json:"folderId"` + LabelName string `json:"folderName"` + FolderSlug string `json:"folderSlug"` } // SiteMeta holds information associated with an Organization. diff --git a/documize/api/request/document.go b/documize/api/request/document.go index dc95a25e..7d7947d2 100644 --- a/documize/api/request/document.go +++ b/documize/api/request/document.go @@ -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, - 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 WHERE search.documentid = document.refid AND search.orgid=? AND document.template=0 ` + tagQuery + `AND document.labelid IN