mirror of
https://github.com/discourse/discourse.git
synced 2024-11-26 13:03:39 +08:00
FEATURE: advanced search filters for view count
This commit is contained in:
parent
580383dff3
commit
0c5cd0d1ef
|
@ -12,6 +12,8 @@ const REGEXP_TAGS_PREFIX = /^(tags?:|#(?=[a-z0-9\-]+::tag))/gi;
|
|||
const REGEXP_IN_PREFIX = /^(in|with):/gi;
|
||||
const REGEXP_STATUS_PREFIX = /^status:/gi;
|
||||
const REGEXP_MIN_POST_COUNT_PREFIX = /^min_post_count:/gi;
|
||||
const REGEXP_MIN_VIEW_COUNT_PREFIX = /^min_view_count:/gi;
|
||||
const REGEXP_MAX_VIEW_COUNT_PREFIX = /^max_view_count:/gi;
|
||||
const REGEXP_POST_TIME_PREFIX = /^(before|after):/gi;
|
||||
const REGEXP_TAGS_REPLACE = /(^(tags?:|#(?=[a-z0-9\-]+::tag))|::tag\s?$)/gi;
|
||||
|
||||
|
@ -93,6 +95,8 @@ export default Component.extend({
|
|||
},
|
||||
status: null,
|
||||
min_post_count: null,
|
||||
min_view_count: null,
|
||||
max_view_count: null,
|
||||
time: {
|
||||
when: "before",
|
||||
days: null,
|
||||
|
@ -161,6 +165,16 @@ export default Component.extend({
|
|||
"searchedTerms.min_post_count",
|
||||
REGEXP_MIN_POST_COUNT_PREFIX
|
||||
);
|
||||
|
||||
this.setSearchedTermValue(
|
||||
"searchedTerms.min_view_count",
|
||||
REGEXP_MIN_VIEW_COUNT_PREFIX
|
||||
);
|
||||
|
||||
this.setSearchedTermValue(
|
||||
"searchedTerms.max_view_count",
|
||||
REGEXP_MAX_VIEW_COUNT_PREFIX
|
||||
);
|
||||
},
|
||||
|
||||
findSearchTerms() {
|
||||
|
@ -345,6 +359,18 @@ export default Component.extend({
|
|||
this._updateSearchTermForMinPostCount();
|
||||
},
|
||||
|
||||
@action
|
||||
onChangeSearchTermMinViewCount(value) {
|
||||
this.set("searchedTerms.min_view_count", value.length ? value : null);
|
||||
this._updateSearchTermForMinViewCount();
|
||||
},
|
||||
|
||||
@action
|
||||
onChangeSearchTermMaxViewCount(value) {
|
||||
this.set("searchedTerms.max_view_count", value.length ? value : null);
|
||||
this._updateSearchTermForMaxViewCount();
|
||||
},
|
||||
|
||||
@action
|
||||
onChangeSearchTermForIn(value) {
|
||||
this.set("searchedTerms.in", value);
|
||||
|
@ -627,6 +653,50 @@ export default Component.extend({
|
|||
}
|
||||
},
|
||||
|
||||
_updateSearchTermForMinViewCount() {
|
||||
const match = this.filterBlocks(REGEXP_MIN_VIEW_COUNT_PREFIX);
|
||||
const viewsCountFilter = this.get("searchedTerms.min_view_count");
|
||||
let searchTerm = this.searchTerm || "";
|
||||
|
||||
if (viewsCountFilter) {
|
||||
if (match.length !== 0) {
|
||||
searchTerm = searchTerm.replace(
|
||||
match[0],
|
||||
`min_view_count:${viewsCountFilter}`
|
||||
);
|
||||
} else {
|
||||
searchTerm += ` min_view_count:${viewsCountFilter}`;
|
||||
}
|
||||
|
||||
this._updateSearchTerm(searchTerm);
|
||||
} else if (match.length !== 0) {
|
||||
searchTerm = searchTerm.replace(match[0], "");
|
||||
this._updateSearchTerm(searchTerm);
|
||||
}
|
||||
},
|
||||
|
||||
_updateSearchTermForMaxViewCount() {
|
||||
const match = this.filterBlocks(REGEXP_MAX_VIEW_COUNT_PREFIX);
|
||||
const viewsCountFilter = this.get("searchedTerms.max_view_count");
|
||||
let searchTerm = this.searchTerm || "";
|
||||
|
||||
if (viewsCountFilter) {
|
||||
if (match.length !== 0) {
|
||||
searchTerm = searchTerm.replace(
|
||||
match[0],
|
||||
`max_view_count:${viewsCountFilter}`
|
||||
);
|
||||
} else {
|
||||
searchTerm += ` max_view_count:${viewsCountFilter}`;
|
||||
}
|
||||
|
||||
this._updateSearchTerm(searchTerm);
|
||||
} else if (match.length !== 0) {
|
||||
searchTerm = searchTerm.replace(match[0], "");
|
||||
this._updateSearchTerm(searchTerm);
|
||||
}
|
||||
},
|
||||
|
||||
_updateSearchTerm(searchTerm) {
|
||||
this.onChangeSearchTerm(searchTerm.trim());
|
||||
},
|
||||
|
|
|
@ -160,6 +160,33 @@
|
|||
}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group pull-left">
|
||||
<label class="control-label" for="search-min-view-count">{{i18n "search.advanced.min_view_count.label"}}</label>
|
||||
<div class="controls">
|
||||
{{input
|
||||
type="number"
|
||||
value=(readonly searchedTerms.min_view_count)
|
||||
class="input-small"
|
||||
id="search-min-view-count"
|
||||
input=(action "onChangeSearchTermMinViewCount" value="target.value")
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group pull-left">
|
||||
<label class="control-label" for="search-max-view-count">{{i18n "search.advanced.max_view_count.label"}}</label>
|
||||
<div class="controls">
|
||||
{{input
|
||||
type="number"
|
||||
value=(readonly searchedTerms.max_view_count)
|
||||
class="input-small"
|
||||
id="search-max-view-count"
|
||||
input=(action "onChangeSearchTermMaxViewCount" value="target.value")
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{plugin-outlet name="advanced-search-options-below" args=(hash searchedTerms=searchedTerms onChangeSearchedTermField=onChangeSearchedTermField) tagName=""}}
|
||||
|
|
|
@ -2124,6 +2124,10 @@ en:
|
|||
label: Posted
|
||||
before: before
|
||||
after: after
|
||||
min_view_count:
|
||||
label: Minimum View Count
|
||||
max_view_count:
|
||||
label: Maximum View Count
|
||||
|
||||
hamburger_menu: "go to another topic list or category"
|
||||
new_item: "new"
|
||||
|
|
|
@ -637,6 +637,14 @@ class Search
|
|||
)", file_extensions: file_extensions)
|
||||
end
|
||||
|
||||
advanced_filter(/^min_view_count:(\d+)$/i) do |posts, match|
|
||||
posts.where("topics.views >= ?", match.to_i)
|
||||
end
|
||||
|
||||
advanced_filter(/^max_view_count:(\d+)$/i) do |posts, match|
|
||||
posts.where("topics.views <= ?", match.to_i)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def search_tags(posts, match, positive:)
|
||||
|
|
|
@ -1393,6 +1393,16 @@ describe Search do
|
|||
])
|
||||
end
|
||||
|
||||
it 'can filter by topic views' do
|
||||
topic = Fabricate(:topic, views: 100)
|
||||
topic2 = Fabricate(:topic, views: 200)
|
||||
post = Fabricate(:post, raw: 'Topic', topic: topic)
|
||||
post2 = Fabricate(:post, raw: 'Topic', topic: topic2)
|
||||
|
||||
expect(Search.execute('Topic min_view_count:150').posts.map(&:id)).to eq([post2.id])
|
||||
expect(Search.execute('Topic max_view_count:150').posts.map(&:id)).to eq([post.id])
|
||||
end
|
||||
|
||||
it 'can search for terms with dots' do
|
||||
post = Fabricate(:post, raw: 'Will.2000 Will.Bob.Bill...')
|
||||
expect(Search.execute('bill').posts.map(&:id)).to eq([post.id])
|
||||
|
|
Loading…
Reference in New Issue
Block a user