mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 11:23:25 +08:00
FEATURE: advanced search option for max posts count (#10761)
This commit adds an option to search for max posts count and updates the UI for posts count search to show a min/max range in single line.
This commit is contained in:
parent
4d1b18f4c6
commit
f7940b1d20
|
@ -12,6 +12,7 @@ const REGEXP_TAGS_PREFIX = /^(tags?:|#(?=[a-z0-9\-]+::tag))/gi;
|
||||||
const REGEXP_IN_PREFIX = /^(in|with):/gi;
|
const REGEXP_IN_PREFIX = /^(in|with):/gi;
|
||||||
const REGEXP_STATUS_PREFIX = /^status:/gi;
|
const REGEXP_STATUS_PREFIX = /^status:/gi;
|
||||||
const REGEXP_MIN_POSTS_PREFIX = /^min_posts:/gi;
|
const REGEXP_MIN_POSTS_PREFIX = /^min_posts:/gi;
|
||||||
|
const REGEXP_MAX_POSTS_PREFIX = /^max_posts:/gi;
|
||||||
const REGEXP_MIN_VIEWS_PREFIX = /^min_views:/gi;
|
const REGEXP_MIN_VIEWS_PREFIX = /^min_views:/gi;
|
||||||
const REGEXP_MAX_VIEWS_PREFIX = /^max_views:/gi;
|
const REGEXP_MAX_VIEWS_PREFIX = /^max_views:/gi;
|
||||||
const REGEXP_POST_TIME_PREFIX = /^(before|after):/gi;
|
const REGEXP_POST_TIME_PREFIX = /^(before|after):/gi;
|
||||||
|
@ -95,6 +96,7 @@ export default Component.extend({
|
||||||
},
|
},
|
||||||
status: null,
|
status: null,
|
||||||
min_posts: null,
|
min_posts: null,
|
||||||
|
max_posts: null,
|
||||||
min_views: null,
|
min_views: null,
|
||||||
max_views: null,
|
max_views: null,
|
||||||
time: {
|
time: {
|
||||||
|
@ -166,6 +168,11 @@ export default Component.extend({
|
||||||
REGEXP_MIN_POSTS_PREFIX
|
REGEXP_MIN_POSTS_PREFIX
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.setSearchedTermValue(
|
||||||
|
"searchedTerms.max_posts",
|
||||||
|
REGEXP_MAX_POSTS_PREFIX
|
||||||
|
);
|
||||||
|
|
||||||
this.setSearchedTermValue(
|
this.setSearchedTermValue(
|
||||||
"searchedTerms.min_views",
|
"searchedTerms.min_views",
|
||||||
REGEXP_MIN_VIEWS_PREFIX
|
REGEXP_MIN_VIEWS_PREFIX
|
||||||
|
@ -359,6 +366,12 @@ export default Component.extend({
|
||||||
this._updateSearchTermForMinPostCount();
|
this._updateSearchTermForMinPostCount();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@action
|
||||||
|
onChangeSearchTermMaxPostCount(value) {
|
||||||
|
this.set("searchedTerms.max_posts", value.length ? value : null);
|
||||||
|
this._updateSearchTermForMaxPostCount();
|
||||||
|
},
|
||||||
|
|
||||||
@action
|
@action
|
||||||
onChangeSearchTermMinViews(value) {
|
onChangeSearchTermMinViews(value) {
|
||||||
this.set("searchedTerms.min_views", value.length ? value : null);
|
this.set("searchedTerms.min_views", value.length ? value : null);
|
||||||
|
@ -653,6 +666,28 @@ export default Component.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_updateSearchTermForMaxPostCount() {
|
||||||
|
const match = this.filterBlocks(REGEXP_MAX_POSTS_PREFIX);
|
||||||
|
const postsCountFilter = this.get("searchedTerms.max_posts");
|
||||||
|
let searchTerm = this.searchTerm || "";
|
||||||
|
|
||||||
|
if (postsCountFilter) {
|
||||||
|
if (match.length !== 0) {
|
||||||
|
searchTerm = searchTerm.replace(
|
||||||
|
match[0],
|
||||||
|
`max_posts:${postsCountFilter}`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
searchTerm += ` max_posts:${postsCountFilter}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._updateSearchTerm(searchTerm);
|
||||||
|
} else if (match.length !== 0) {
|
||||||
|
searchTerm = searchTerm.replace(match[0], "");
|
||||||
|
this._updateSearchTerm(searchTerm);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_updateSearchTermForMinViews() {
|
_updateSearchTermForMinViews() {
|
||||||
const match = this.filterBlocks(REGEXP_MIN_VIEWS_PREFIX);
|
const match = this.filterBlocks(REGEXP_MIN_VIEWS_PREFIX);
|
||||||
const viewsCountFilter = this.get("searchedTerms.min_views");
|
const viewsCountFilter = this.get("searchedTerms.min_views");
|
||||||
|
|
|
@ -148,22 +148,39 @@
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group pull-left">
|
|
||||||
|
<div class="count-group control-group pull-left">
|
||||||
<label class="control-label" for="search-min-post-count">{{i18n "search.advanced.post.count.label"}}</label>
|
<label class="control-label" for="search-min-post-count">{{i18n "search.advanced.post.count.label"}}</label>
|
||||||
<div class="controls">
|
<div class="count pull-left">
|
||||||
{{input
|
<div class="controls">
|
||||||
type="number"
|
{{input
|
||||||
value=(readonly searchedTerms.min_posts)
|
type="number"
|
||||||
class="input-small"
|
value=(readonly searchedTerms.min_posts)
|
||||||
id="search-min-post-count"
|
class="input-small"
|
||||||
input=(action "onChangeSearchTermMinPostCount" value="target.value")
|
id="search-min-post-count"
|
||||||
}}
|
input=(action "onChangeSearchTermMinPostCount" value="target.value")
|
||||||
|
placeholder=(i18n "search.advanced.post.min.placeholder")
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="count-dash">—</span>
|
||||||
|
<div class="count pull-right">
|
||||||
|
<div class="controls">
|
||||||
|
{{input
|
||||||
|
type="number"
|
||||||
|
value=(readonly searchedTerms.max_posts)
|
||||||
|
class="input-small"
|
||||||
|
id="search-max-post-count"
|
||||||
|
input=(action "onChangeSearchTermMaxPostCount" value="target.value")
|
||||||
|
placeholder=(i18n "search.advanced.post.max.placeholder")
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="views control-group pull-left">
|
<div class="count-group control-group pull-left">
|
||||||
<label class="control-label">{{i18n "search.advanced.views.label"}}</label>
|
<label class="control-label">{{i18n "search.advanced.views.label"}}</label>
|
||||||
<div class="views-count pull-left">
|
<div class="count pull-left">
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
{{input
|
{{input
|
||||||
type="number"
|
type="number"
|
||||||
|
@ -175,8 +192,8 @@
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span class="views-count-dash">–</span>
|
<span class="count-dash">—</span>
|
||||||
<div class="views-count pull-right">
|
<div class="count pull-right">
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
{{input
|
{{input
|
||||||
type="number"
|
type="number"
|
||||||
|
|
|
@ -164,13 +164,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.views {
|
.count-group {
|
||||||
.views-count {
|
.count {
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
width: 45%;
|
width: 45%;
|
||||||
}
|
}
|
||||||
.views-count-dash {
|
.count-dash {
|
||||||
padding-left: 10px;
|
padding-left: 6px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2119,7 +2119,11 @@ en:
|
||||||
single_user: contain a single user
|
single_user: contain a single user
|
||||||
post:
|
post:
|
||||||
count:
|
count:
|
||||||
label: Minimum Posts
|
label: Posts
|
||||||
|
min:
|
||||||
|
placeholder: minimum
|
||||||
|
max:
|
||||||
|
placeholder: maximum
|
||||||
time:
|
time:
|
||||||
label: Posted
|
label: Posted
|
||||||
before: before
|
before: before
|
||||||
|
|
|
@ -369,12 +369,16 @@ class Search
|
||||||
posts.where("topics.posts_count = ?", match.to_i)
|
posts.where("topics.posts_count = ?", match.to_i)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
advanced_filter(/^min_post_count:(\d+)$/i) do |posts, match|
|
||||||
|
posts.where("topics.posts_count >= ?", match.to_i)
|
||||||
|
end
|
||||||
|
|
||||||
advanced_filter(/^min_posts:(\d+)$/i) do |posts, match|
|
advanced_filter(/^min_posts:(\d+)$/i) do |posts, match|
|
||||||
posts.where("topics.posts_count >= ?", match.to_i)
|
posts.where("topics.posts_count >= ?", match.to_i)
|
||||||
end
|
end
|
||||||
|
|
||||||
advanced_filter(/^min_post_count:(\d+)$/i) do |posts, match|
|
advanced_filter(/^max_posts:(\d+)$/i) do |posts, match|
|
||||||
posts.where("topics.posts_count >= ?", match.to_i)
|
posts.where("topics.posts_count <= ?", match.to_i)
|
||||||
end
|
end
|
||||||
|
|
||||||
advanced_filter(/^in:first|^f$/i) do |posts|
|
advanced_filter(/^in:first|^f$/i) do |posts|
|
||||||
|
|
|
@ -1279,6 +1279,7 @@ describe Search do
|
||||||
expect(Search.execute('test posts_count:1').posts.length).to eq(1)
|
expect(Search.execute('test posts_count:1').posts.length).to eq(1)
|
||||||
expect(Search.execute('test min_post_count:1').posts.length).to eq(1)
|
expect(Search.execute('test min_post_count:1').posts.length).to eq(1)
|
||||||
expect(Search.execute('test min_posts:1').posts.length).to eq(1)
|
expect(Search.execute('test min_posts:1').posts.length).to eq(1)
|
||||||
|
expect(Search.execute('test max_posts:2').posts.length).to eq(1)
|
||||||
|
|
||||||
topic.update(closed: true)
|
topic.update(closed: true)
|
||||||
second_topic.update(category: public_category)
|
second_topic.update(category: public_category)
|
||||||
|
|
|
@ -396,6 +396,26 @@ QUnit.test(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
QUnit.test(
|
||||||
|
"update max post count through advanced search ui",
|
||||||
|
async (assert) => {
|
||||||
|
await visit("/search");
|
||||||
|
await fillIn(".search-query", "none");
|
||||||
|
await fillIn("#search-max-post-count", "5");
|
||||||
|
|
||||||
|
assert.equal(
|
||||||
|
find(".search-advanced-options #search-max-post-count").val(),
|
||||||
|
"5",
|
||||||
|
'has "5" populated'
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
find(".search-query").val(),
|
||||||
|
"none max_posts:5",
|
||||||
|
'has updated search term to "none max_posts:5"'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
QUnit.test("validate advanced search when initially empty", async (assert) => {
|
QUnit.test("validate advanced search when initially empty", async (assert) => {
|
||||||
await visit("/search?expanded=true");
|
await visit("/search?expanded=true");
|
||||||
await click(".search-advanced-options .in-likes");
|
await click(".search-advanced-options .in-likes");
|
||||||
|
|
Loading…
Reference in New Issue
Block a user