Skip to content

Commit a72846f

Browse files
committed
Auto merge of #2214 - RobbieClarken:sort-by-newly-added, r=jtgeibel
Enable sorting crates by most recently added This change adds the option to sort crates by "Newly Added" on the following pages: - `/crates` - `/search` - `/users/:user_id` - `/teams/:team_id` - `/keywords/:keyword_id` - `/categories/:category_id` - `/me/crates` Sorting is performed using the `crates.created_at` column. I've put "Newly Added" as the last option in the dropdown: <img width="258" alt="sort-by-newly-added" src="https://user-images.githubusercontent.com/663161/75087201-2a7ff500-558d-11ea-896b-2e82de37811d.png"> Let me know if you would like a different label or for the order to be different. I couldn't find any existing frontend tests of changing sort order. I'd be happy to add some as part of this PR if they would be valuable. Closes #1919.
2 parents 5202619 + 975de2a commit a72846f

File tree

17 files changed

+106
-3
lines changed

17 files changed

+106
-3
lines changed

app/controllers/category/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ export default Controller.extend(PaginationMixin, {
1919
return 'All-Time Downloads';
2020
} else if (this.sort === 'alpha') {
2121
return 'Alphabetical';
22+
} else if (this.sort === 'new') {
23+
return 'Newly Added';
2224
} else if (this.get('sort') === 'recent-updates') {
2325
return 'Recent Updates';
2426
} else {

app/controllers/crates.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ export default Controller.extend(PaginationMixin, {
2121
return 'Recent Downloads';
2222
} else if (this.get('sort') === 'recent-updates') {
2323
return 'Recent Updates';
24+
} else if (this.sort === 'new') {
25+
return 'Newly Added';
2426
} else {
2527
return 'Alphabetical';
2628
}

app/controllers/keyword/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ export default Controller.extend(PaginationMixin, {
1717
return 'All-Time Downloads';
1818
} else if (this.sort === 'alpha') {
1919
return 'Alphabetical';
20+
} else if (this.sort === 'new') {
21+
return 'Newly Added';
2022
} else if (this.get('sort') === 'recent-updates') {
2123
return 'Recent Updates';
2224
} else {

app/controllers/me/crates.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ export default Controller.extend(PaginationMixin, {
2121
return 'Recent Downloads';
2222
} else if (this.get('sort') === 'recent-updates') {
2323
return 'Recent Updates';
24+
} else if (this.sort === 'new') {
25+
return 'Newly Added';
2426
} else {
2527
return 'Alphabetical';
2628
}

app/controllers/search.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ export default Controller.extend(PaginationMixin, {
3333
return 'Recent Downloads';
3434
} else if (this.get('sort') === 'recent-updates') {
3535
return 'Recent Updates';
36+
} else if (this.sort === 'new') {
37+
return 'Newly Added';
3638
} else {
3739
return 'Relevance';
3840
}

app/controllers/team.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ export default Controller.extend(PaginationMixin, {
1919
return 'Recent Downloads';
2020
} else if (this.get('sort') === 'recent-updates') {
2121
return 'Recent Updates';
22+
} else if (this.sort === 'new') {
23+
return 'Newly Added';
2224
} else {
2325
return 'Alphabetical';
2426
}

app/controllers/user.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ export default Controller.extend(PaginationMixin, {
2020
return 'Recent Downloads';
2121
} else if (this.get('sort') === 'recent-updates') {
2222
return 'Recent Updates';
23+
} else if (this.sort === 'new') {
24+
return 'Newly Added';
2325
} else {
2426
return 'Alphabetical';
2527
}

app/templates/category/index.hbs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@
7777
Recent Updates
7878
</LinkTo>
7979
</li>
80+
<li>
81+
<LinkTo @query={{hash sort="new"}}>
82+
Newly Added
83+
</LinkTo>
84+
</li>
8085
</dd.Content>
8186
</Dropdown>
8287
</div>
@@ -88,4 +93,4 @@
8893
{{/each}}
8994
</div>
9095

91-
<Pagination @pages={{this.pages}} @prevPage={{this.prevPage}} @nextPage={{this.nextPage}} />
96+
<Pagination @pages={{this.pages}} @prevPage={{this.prevPage}} @nextPage={{this.nextPage}} />

app/templates/crates.hbs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@
6565
Recent Updates
6666
</LinkTo>
6767
</li>
68+
<li>
69+
<LinkTo @query={{hash page=1 sort="new"}}>
70+
Newly Added
71+
</LinkTo>
72+
</li>
6873
</dd.Content>
6974
</Dropdown>
7075
</div>

app/templates/keyword/index.hbs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@
4545
Recent Updates
4646
</LinkTo>
4747
</li>
48+
<li>
49+
<LinkTo @query={{hash sort="new"}}>
50+
Newly Added
51+
</LinkTo>
52+
</li>
4853
</dd.Content>
4954
</Dropdown>
5055
</div>

app/templates/me/crates.hbs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@
4646
Recent Updates
4747
</LinkTo>
4848
</li>
49+
<li>
50+
<LinkTo @query={{hash sort="new"}}>
51+
Newly Added
52+
</LinkTo>
53+
</li>
4954
</dd.Content>
5055
</Dropdown>
5156
</div>
@@ -57,4 +62,4 @@
5762
{{/each}}
5863
</div>
5964

60-
<Pagination @pages={{this.pages}} @prevPage={{this.prevPage}} @nextPage={{this.nextPage}} />
65+
<Pagination @pages={{this.pages}} @prevPage={{this.prevPage}} @nextPage={{this.nextPage}} />

app/templates/search.hbs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@
5757
Recent Updates
5858
</LinkTo>
5959
</li>
60+
<li>
61+
<LinkTo @query={{hash page=1 sort="new"}}>
62+
Newly Added
63+
</LinkTo>
64+
</li>
6065
</dd.Content>
6166
</Dropdown>
6267
</div>

app/templates/team.hbs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@
6060
Recent Updates
6161
</LinkTo>
6262
</li>
63+
<li>
64+
<LinkTo @query={{hash sort="new"}}>
65+
Newly Added
66+
</LinkTo>
67+
</li>
6368
</dd.Content>
6469
</Dropdown>
6570
</div>

app/templates/user.hbs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@
5151
Recent Updates
5252
</LinkTo>
5353
</li>
54+
<li>
55+
<LinkTo @query={{hash sort="new"}}>
56+
Newly Added
57+
</LinkTo>
58+
</li>
5459
</dd.Content>
5560
</Dropdown>
5661
</div>

src/controllers/krate/search.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ pub fn search(req: &mut dyn Request) -> AppResult<Response> {
178178
query = query.then_order_by(recent_crate_downloads::downloads.desc().nulls_last())
179179
} else if sort == Some("recent-updates") {
180180
query = query.order(crates::updated_at.desc());
181+
} else if sort == Some("new") {
182+
query = query.order(crates::created_at.desc());
181183
} else {
182184
query = query.then_order_by(crates::name.asc())
183185
}

src/tests/krate.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ fn exact_match_first_on_queries() {
243243
}
244244

245245
#[test]
246+
#[allow(clippy::cognitive_complexity)]
246247
fn index_sorting() {
247248
let (app, anon, user) = TestApp::init().with_user();
248249
let user = user.as_model();
@@ -271,6 +272,24 @@ fn index_sorting() {
271272
.downloads(999_999)
272273
.expect_build(conn);
273274

275+
// Set the created at column for each crate
276+
update(&krate1)
277+
.set(crates::created_at.eq(now - 4.weeks()))
278+
.execute(conn)
279+
.unwrap();
280+
update(&krate2)
281+
.set(crates::created_at.eq(now - 1.weeks()))
282+
.execute(conn)
283+
.unwrap();
284+
update(&krate3)
285+
.set(crates::created_at.eq(now - 2.weeks()))
286+
.execute(conn)
287+
.unwrap();
288+
update(&krate4)
289+
.set(crates::created_at.eq(now - 3.weeks()))
290+
.execute(conn)
291+
.unwrap();
292+
274293
// Set the updated at column for each crate
275294
update(&krate1)
276295
.set(crates::updated_at.eq(now - 3.weeks()))
@@ -314,6 +333,14 @@ fn index_sorting() {
314333
assert_eq!(json.crates[2].name, "bar_sort");
315334
assert_eq!(json.crates[3].name, "foo_sort");
316335

336+
// Sort by new
337+
let json = anon.search("sort=new");
338+
assert_eq!(json.meta.total, 4);
339+
assert_eq!(json.crates[0].name, "bar_sort");
340+
assert_eq!(json.crates[1].name, "baz_sort");
341+
assert_eq!(json.crates[2].name, "other_sort");
342+
assert_eq!(json.crates[3].name, "foo_sort");
343+
317344
// Test for bug with showing null results first when sorting
318345
// by descending downloads
319346
let json = anon.search("sort=recent-downloads");
@@ -354,6 +381,24 @@ fn exact_match_on_queries_with_sort() {
354381
.downloads(999_999)
355382
.expect_build(conn);
356383

384+
// Set the created at column for each crate
385+
update(&krate1)
386+
.set(crates::created_at.eq(now - 4.weeks()))
387+
.execute(conn)
388+
.unwrap();
389+
update(&krate2)
390+
.set(crates::created_at.eq(now - 1.weeks()))
391+
.execute(conn)
392+
.unwrap();
393+
update(&krate3)
394+
.set(crates::created_at.eq(now - 2.weeks()))
395+
.execute(conn)
396+
.unwrap();
397+
update(&krate4)
398+
.set(crates::created_at.eq(now - 3.weeks()))
399+
.execute(conn)
400+
.unwrap();
401+
357402
// Set the updated at column for each crate
358403
update(&krate1)
359404
.set(crates::updated_at.eq(now - 3.weeks()))
@@ -413,6 +458,13 @@ fn exact_match_on_queries_with_sort() {
413458
assert_eq!(json.crates[1].name, "bar_sort");
414459
assert_eq!(json.crates[2].name, "foo_sort");
415460

461+
// Sort by new
462+
let json = anon.search("q=bar_sort&sort=new");
463+
assert_eq!(json.meta.total, 3);
464+
assert_eq!(json.crates[0].name, "bar_sort");
465+
assert_eq!(json.crates[1].name, "baz_sort");
466+
assert_eq!(json.crates[2].name, "foo_sort");
467+
416468
// Test for bug with showing null results first when sorting
417469
// by descending downloads
418470
let json = anon.search("sort=recent-downloads");

tests/acceptance/search-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ module('Acceptance | search', function(hooks) {
3737
assert.dom('[data-test-search-nav]').hasText('Displaying 1-7 of 7 total results');
3838
assert
3939
.dom('[data-test-search-sort]')
40-
.hasText('Sort by Relevance Relevance All-Time Downloads Recent Downloads Recent Updates');
40+
.hasText('Sort by Relevance Relevance All-Time Downloads Recent Downloads Recent Updates Newly Added');
4141
assert.dom('[data-test-crate-row="0"] [data-test-crate-link]').hasText('kinetic-rust');
4242
assert.dom('[data-test-crate-row="0"] [data-test-version-badge]').hasAttribute('alt', '0.0.16');
4343

0 commit comments

Comments
 (0)