mirror of
https://github.com/documize/community.git
synced 2025-07-23 15:19:42 +02:00
Auto-load serach results
This commit is contained in:
parent
c92ab3a589
commit
ddd90a4aaf
9 changed files with 804 additions and 763 deletions
|
@ -416,28 +416,30 @@ func (h *Handler) SearchDocuments(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record user search history
|
// Record user search history
|
||||||
if len(results) > 0 {
|
if !options.SkipLog {
|
||||||
go h.recordSearchActivity(ctx, results, options.Keywords)
|
if len(results) > 0 {
|
||||||
} else {
|
go h.recordSearchActivity(ctx, results, options.Keywords)
|
||||||
ctx.Transaction, err = h.Runtime.Db.Beginx()
|
} else {
|
||||||
if err != nil {
|
ctx.Transaction, err = h.Runtime.Db.Beginx()
|
||||||
h.Runtime.Log.Error(method, err)
|
if err != nil {
|
||||||
return
|
h.Runtime.Log.Error(method, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = h.Store.Activity.RecordUserActivity(ctx, activity.UserActivity{
|
||||||
|
LabelID: "",
|
||||||
|
DocumentID: "",
|
||||||
|
Metadata: options.Keywords,
|
||||||
|
SourceType: activity.SourceTypeSearch,
|
||||||
|
ActivityType: activity.TypeSearched})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
ctx.Transaction.Rollback()
|
||||||
|
h.Runtime.Log.Error(method, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Transaction.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
err = h.Store.Activity.RecordUserActivity(ctx, activity.UserActivity{
|
|
||||||
LabelID: "",
|
|
||||||
DocumentID: "",
|
|
||||||
Metadata: options.Keywords,
|
|
||||||
SourceType: activity.SourceTypeSearch,
|
|
||||||
ActivityType: activity.TypeSearched})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
ctx.Transaction.Rollback()
|
|
||||||
h.Runtime.Log.Error(method, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.Transaction.Commit()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h.Store.Audit.Record(ctx, audit.EventTypeSearch)
|
h.Store.Audit.Record(ctx, audit.EventTypeSearch)
|
||||||
|
|
File diff suppressed because one or more lines are too long
56
gui/app/components/search/search-view.js
Normal file
56
gui/app/components/search/search-view.js
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||||
|
//
|
||||||
|
// 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 <sales@documize.com>.
|
||||||
|
//
|
||||||
|
// https://documize.com
|
||||||
|
|
||||||
|
import { A } from '@ember/array';
|
||||||
|
import { inject as service } from '@ember/service';
|
||||||
|
import Component from '@ember/component';
|
||||||
|
|
||||||
|
export default Component.extend({
|
||||||
|
searchSvc: service('search'),
|
||||||
|
results: A([]),
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this._super(...arguments);
|
||||||
|
this.fetch();
|
||||||
|
},
|
||||||
|
|
||||||
|
fetch() {
|
||||||
|
let payload = {
|
||||||
|
keywords: this.get('filter'),
|
||||||
|
doc: this.get('matchDoc'),
|
||||||
|
attachment: this.get('matchFile'),
|
||||||
|
tag: this.get('matchTag'),
|
||||||
|
content: this.get('matchContent'),
|
||||||
|
slog: this.get('slog')
|
||||||
|
};
|
||||||
|
|
||||||
|
payload.keywords = payload.keywords.trim();
|
||||||
|
|
||||||
|
if (payload.keywords.length == 0) {
|
||||||
|
this.set('results', A([]));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!payload.doc && !payload.tag && !payload.content && !payload.attachment) {
|
||||||
|
this.set('results', A([]));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.get('searchSvc').find(payload).then( (response) => {
|
||||||
|
this.set('results', response);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
onSearch() {
|
||||||
|
this.fetch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -9,49 +9,14 @@
|
||||||
//
|
//
|
||||||
// https://documize.com
|
// https://documize.com
|
||||||
|
|
||||||
import { A } from '@ember/array';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
import Controller from '@ember/controller';
|
import Controller from '@ember/controller';
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
searchService: service('search'),
|
queryParams: ['filter', 'matchDoc', 'matchContent', 'matchTag', 'matchFile', 'slog'],
|
||||||
queryParams: ['filter', 'matchDoc', 'matchContent', 'matchTag', 'matchFile'],
|
|
||||||
filter: '',
|
filter: '',
|
||||||
matchDoc: true,
|
matchDoc: true,
|
||||||
matchContent: true,
|
matchContent: true,
|
||||||
matchTag: false,
|
matchTag: false,
|
||||||
matchFile: false,
|
matchFile: false,
|
||||||
results: A([]),
|
slog: false,
|
||||||
|
|
||||||
fetch() {
|
|
||||||
let self = this;
|
|
||||||
let payload = {
|
|
||||||
keywords: this.get('filter'),
|
|
||||||
doc: this.get('matchDoc'),
|
|
||||||
attachment: this.get('matchFile'),
|
|
||||||
tag: this.get('matchTag'),
|
|
||||||
content: this.get('matchContent')
|
|
||||||
};
|
|
||||||
|
|
||||||
payload.keywords = payload.keywords.trim();
|
|
||||||
|
|
||||||
if (payload.keywords.length == 0) {
|
|
||||||
this.set('results', A([]));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!payload.doc && !payload.tag && !payload.content && !payload.attachment) {
|
|
||||||
this.set('results', A([]));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.get('searchService').find(payload).then(function(response) {
|
|
||||||
self.set('results', response);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
onSearch() {
|
|
||||||
this.fetch();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,13 +13,6 @@ import Route from '@ember/routing/route';
|
||||||
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
|
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
|
||||||
|
|
||||||
export default Route.extend(AuthenticatedRouteMixin, {
|
export default Route.extend(AuthenticatedRouteMixin, {
|
||||||
queryParams: {
|
|
||||||
filter: {
|
|
||||||
replace: true,
|
|
||||||
refreshModel: false,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
activate() {
|
activate() {
|
||||||
this.get('browser').setTitle('Search');
|
this.get('browser').setTitle('Search');
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,34 +7,4 @@
|
||||||
{{/toolbar/t-actions}}
|
{{/toolbar/t-actions}}
|
||||||
{{/toolbar/t-toolbar}}
|
{{/toolbar/t-toolbar}}
|
||||||
|
|
||||||
<div class="container">
|
{{search/search-view filter=filter matchDoc=matchDoc matchContent=matchContent matchTag=matchTag matchFile=matchFile slog=slog}}
|
||||||
<div class="view-search mt-5">
|
|
||||||
<div class="heading">Search</div>
|
|
||||||
<form onsubmit={{action 'onSearch'}}>
|
|
||||||
<div class="form-group mt-4">
|
|
||||||
{{focus-input type="text" value=filter class="form-control mb-4" placeholder='a OR b, x AND y, "phrase mat*"'}}
|
|
||||||
<div class="form-check form-check-inline">
|
|
||||||
{{input type="checkbox" id="search-1" class="form-check-input" checked=matchDoc}}
|
|
||||||
<label class="form-check-label" for="search-1"> document title</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-check-inline">
|
|
||||||
{{input type="checkbox" id="search-2" class="form-check-input" checked=matchContent}}
|
|
||||||
<label class="form-check-label" for="search-2"> content</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-check-inline">
|
|
||||||
{{input type="checkbox" id="search-3" class="form-check-input" checked=matchTag}}
|
|
||||||
<label class="form-check-label" for="search-3"> tag name</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-check-inline">
|
|
||||||
{{input type="checkbox" id="search-4" class="form-check-input" checked=matchFile}}
|
|
||||||
<label class="form-check-label" for="search-4"> attachment name</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<button class="btn btn-success" {{action 'onSearch'}}>Search</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
{{search/search-results results=results keywords=filter}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<div class="col-12 col-sm-3 heading">Tags</div>
|
<div class="col-12 col-sm-3 heading">Tags</div>
|
||||||
<div class="col-12 col-sm-9 value">
|
<div class="col-12 col-sm-9 value">
|
||||||
{{#each tagz as |t index|}}
|
{{#each tagz as |t index|}}
|
||||||
{{#link-to 'search' (query-params filter=t matchTag=true matchDoc=false matchContent=false matchAttachment=false)}}
|
{{#link-to 'search' (query-params filter=t matchTag=true matchDoc=false matchContent=false matchFile=false)}}
|
||||||
{{concat '#' t}}
|
{{concat '#' t}}
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
31
gui/app/templates/components/search/search-view.hbs
Normal file
31
gui/app/templates/components/search/search-view.hbs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<div class="container">
|
||||||
|
<div class="view-search mt-5">
|
||||||
|
<div class="heading">Search</div>
|
||||||
|
<form onsubmit={{action 'onSearch'}}>
|
||||||
|
<div class="form-group mt-4">
|
||||||
|
{{focus-input type="text" value=filter class="form-control mb-4" placeholder='a OR b, x AND y, "phrase mat*"'}}
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
{{input type="checkbox" id="search-1" class="form-check-input" checked=matchDoc}}
|
||||||
|
<label class="form-check-label" for="search-1"> document title</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
{{input type="checkbox" id="search-2" class="form-check-input" checked=matchContent}}
|
||||||
|
<label class="form-check-label" for="search-2"> content</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
{{input type="checkbox" id="search-3" class="form-check-input" checked=matchTag}}
|
||||||
|
<label class="form-check-label" for="search-3"> tag name</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
{{input type="checkbox" id="search-4" class="form-check-input" checked=matchFile}}
|
||||||
|
<label class="form-check-label" for="search-4"> attachment name</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<button class="btn btn-success" {{action 'onSearch'}}>Search</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{{search/search-results results=results keywords=filter}}
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -18,6 +18,7 @@ type QueryOptions struct {
|
||||||
Tag bool `json:"tag"`
|
Tag bool `json:"tag"`
|
||||||
Attachment bool `json:"attachment"`
|
Attachment bool `json:"attachment"`
|
||||||
Content bool `json:"content"`
|
Content bool `json:"content"`
|
||||||
|
SkipLog bool `json:"slog"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryResult represents 'presentable' search results.
|
// QueryResult represents 'presentable' search results.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue