Commit 80d1cae6 by Greg Price

Add filter menu to forum nav sidebar

The menu allows filtering to unread, unanswered, or flagged threads.
This includes passing through the appropriate query parameters to the
comments service.
parent eaa93bf6
...@@ -137,13 +137,21 @@ describe "DiscussionThreadListView", -> ...@@ -137,13 +137,21 @@ describe "DiscussionThreadListView", ->
</div> </div>
<div class="forum-nav-thread-list-wrapper"> <div class="forum-nav-thread-list-wrapper">
<div class="forum-nav-refine-bar"> <div class="forum-nav-refine-bar">
<span class="forum-nav-sort"> <label class="forum-nav-filter-main">
<select class="forum-nav-filter-main-control">
<option value="all">Show all</option>
<option value="unread">Unread</option>
<option value="unanswered">Unanswered</option>
<option value="flagged">Flagged</option>
</select>
</label>
<label class="forum-nav-sort">
<select class="forum-nav-sort-control"> <select class="forum-nav-sort-control">
<option value="date">by recent activity</option> <option value="date">by recent activity</option>
<option value="comments">by most activity</option> <option value="comments">by most activity</option>
<option value="votes">by most votes</option> <option value="votes">by most votes</option>
</select> </select>
</span> </label>
</div> </div>
</div> </div>
<div class="search-alerts"></div> <div class="search-alerts"></div>
...@@ -201,6 +209,31 @@ describe "DiscussionThreadListView", -> ...@@ -201,6 +209,31 @@ describe "DiscussionThreadListView", ->
collection: discussion collection: discussion
) )
expectFilter = (filterVal) ->
$.ajax.andCallFake((params) ->
_.each(["unread", "unanswered", "flagged"], (paramName)->
if paramName == filterVal
expect(params.data[paramName]).toEqual(true)
else
expect(params.data[paramName]).toBeUndefined()
)
{always: ->}
)
describe "should filter correctly", ->
_.each(["all", "unread", "unanswered", "flagged"], (filterVal) ->
it "for #{filterVal}", ->
expectFilter(filterVal)
@view.$(".forum-nav-filter-main-control").val(filterVal).change()
expect($.ajax).toHaveBeenCalled()
)
it "search should clear filter", ->
expectFilter(null)
@view.$(".forum-nav-filter-main-control").val("flagged")
@view.searchFor("foobar")
expect(@view.$(".forum-nav-filter-main-control").val()).toEqual("all")
checkThreadsOrdering = (view, sort_order, type) -> checkThreadsOrdering = (view, sort_order, type) ->
expect(view.$el.find(".forum-nav-thread").children().length).toEqual(3) expect(view.$el.find(".forum-nav-thread").children().length).toEqual(3)
expect(view.$el.find(".forum-nav-thread:nth-child(1) .forum-nav-thread-title").text()).toEqual(sort_order[0]) expect(view.$el.find(".forum-nav-thread:nth-child(1) .forum-nav-thread-title").text()).toEqual(sort_order[0])
......
...@@ -34,6 +34,8 @@ if Backbone? ...@@ -34,6 +34,8 @@ if Backbone?
retrieveAnotherPage: (mode, options={}, sort_options={}, error=null)-> retrieveAnotherPage: (mode, options={}, sort_options={}, error=null)->
data = { page: @current_page + 1 } data = { page: @current_page + 1 }
if _.contains(["unread", "unanswered", "flagged"], options.filter)
data[options.filter] = true
switch mode switch mode
when 'search' when 'search'
url = DiscussionUtil.urlFor 'search' url = DiscussionUtil.urlFor 'search'
......
...@@ -10,6 +10,7 @@ if Backbone? ...@@ -10,6 +10,7 @@ if Backbone?
"change .forum-nav-sort-control": "sortThreads" "change .forum-nav-sort-control": "sortThreads"
"click .forum-nav-thread-link": "threadSelected" "click .forum-nav-thread-link": "threadSelected"
"click .forum-nav-load-more-link": "loadMorePages" "click .forum-nav-load-more-link": "loadMorePages"
"change .forum-nav-filter-main-control": "chooseFilter"
"change .forum-nav-filter-cohort-control": "chooseCohort" "change .forum-nav-filter-cohort-control": "chooseCohort"
initialize: -> initialize: ->
...@@ -173,7 +174,7 @@ if Backbone? ...@@ -173,7 +174,7 @@ if Backbone?
loadingElem = loadMoreElem.find(".forum-nav-loading") loadingElem = loadMoreElem.find(".forum-nav-loading")
DiscussionUtil.makeFocusTrap(loadingElem) DiscussionUtil.makeFocusTrap(loadingElem)
loadingElem.focus() loadingElem.focus()
options = {} options = {filter: @filter}
switch @mode switch @mode
when 'search' when 'search'
options.search_text = @current_search options.search_text = @current_search
...@@ -378,11 +379,13 @@ if Backbone? ...@@ -378,11 +379,13 @@ if Backbone?
@retrieveDiscussions(discussionIds) @retrieveDiscussions(discussionIds)
@$(".forum-nav-filter-cohort").toggle(item.data('cohorted') == true) @$(".forum-nav-filter-cohort").toggle(item.data('cohorted') == true)
chooseCohort: (event) -> chooseFilter: (event) =>
@filter = $(".forum-nav-filter-main-control :selected").val()
@retrieveFirstPage()
chooseCohort: (event) =>
@group_id = @$('.forum-nav-filter-cohort-control :selected').val() @group_id = @$('.forum-nav-filter-cohort-control :selected').val()
@collection.current_page = 0 @retrieveFirstPage()
@collection.reset()
@loadMorePages(event)
retrieveDiscussion: (discussion_id, callback=null) -> retrieveDiscussion: (discussion_id, callback=null) ->
url = DiscussionUtil.urlFor("retrieve_discussion", discussion_id) url = DiscussionUtil.urlFor("retrieve_discussion", discussion_id)
...@@ -434,6 +437,7 @@ if Backbone? ...@@ -434,6 +437,7 @@ if Backbone?
searchFor: (text) -> searchFor: (text) ->
@clearSearchAlerts() @clearSearchAlerts()
@clearFilters()
@mode = 'search' @mode = 'search'
@current_search = text @current_search = text
url = DiscussionUtil.urlFor("search") url = DiscussionUtil.urlFor("search")
...@@ -500,6 +504,10 @@ if Backbone? ...@@ -500,6 +504,10 @@ if Backbone?
@$(".forum-nav-search-input").val("") @$(".forum-nav-search-input").val("")
@current_search = "" @current_search = ""
clearFilters: ->
@$(".forum-nav-filter-main-control").val("all")
@$(".forum-nav-filter-cohort-control").val("all")
retrieveFollowed: () => retrieveFollowed: () =>
@mode = 'followed' @mode = 'followed'
@retrieveFirstPage() @retrieveFirstPage()
......
...@@ -103,11 +103,24 @@ def get_threads(request, course_id, discussion_id=None, per_page=THREADS_PER_PAG ...@@ -103,11 +103,24 @@ def get_threads(request, course_id, discussion_id=None, per_page=THREADS_PER_PAG
#so by default, a moderator sees all items, and a student sees his cohort #so by default, a moderator sees all items, and a student sees his cohort
query_params = merge_dict(default_query_params, query_params = merge_dict(
strip_none(extract(request.GET, default_query_params,
['page', 'sort_key', strip_none(
'sort_order', 'text', extract(
'commentable_ids', 'flagged']))) request.GET,
[
'page',
'sort_key',
'sort_order',
'text',
'commentable_ids',
'flagged',
'unread',
'unanswered',
]
)
)
)
threads, page, num_pages, corrected_text = cc.Thread.search(query_params) threads, page, num_pages, corrected_text = cc.Thread.search(query_params)
...@@ -368,13 +381,30 @@ def followed_threads(request, course_id, user_id): ...@@ -368,13 +381,30 @@ def followed_threads(request, course_id, user_id):
try: try:
profiled_user = cc.User(id=user_id, course_id=course_id) profiled_user = cc.User(id=user_id, course_id=course_id)
query_params = { default_query_params = {
'page': request.GET.get('page', 1), 'page': 1,
'per_page': THREADS_PER_PAGE, # more than threads_per_page to show more activities 'per_page': THREADS_PER_PAGE, # more than threads_per_page to show more activities
'sort_key': request.GET.get('sort_key', 'date'), 'sort_key': 'date',
'sort_order': request.GET.get('sort_order', 'desc'), 'sort_order': 'desc',
} }
query_params = merge_dict(
default_query_params,
strip_none(
extract(
request.GET,
[
'page',
'sort_key',
'sort_order',
'flagged',
'unread',
'unanswered',
]
)
)
)
threads, page, num_pages = profiled_user.subscribed_threads(query_params) threads, page, num_pages = profiled_user.subscribed_threads(query_params)
query_params['page'] = page query_params['page'] = page
query_params['num_pages'] = num_pages query_params['num_pages'] = num_pages
......
...@@ -127,21 +127,35 @@ ...@@ -127,21 +127,35 @@
background-color: $gray-l5; background-color: $gray-l5;
padding: ($baseline/4) ($baseline/2); padding: ($baseline/4) ($baseline/2);
color: $black; color: $black;
text-align: right;
}
.forum-nav-filter-main {
@include box-sizing(border-box);
display: inline-block;
width: 50%;
text-align: left;
}
.forum-nav-filter-cohort, .forum-nav-sort {
@include box-sizing(border-box);
display: inline-block;
width: 50%;
text-align: right;
} }
%forum-nav-select { %forum-nav-select {
border: none; border: none;
max-width: 100%; max-width: 100%;
background-color: transparent; background-color: transparent;
font: inherit;
} }
.forum-nav-filter-cohort-control { .forum-nav-filter-main-control {
@extend %forum-nav-select; @extend %forum-nav-select;
} }
.forum-nav-sort { .forum-nav-filter-cohort-control {
float: right; @extend %forum-nav-select;
} }
.forum-nav-sort-control { .forum-nav-sort-control {
......
...@@ -66,9 +66,16 @@ ...@@ -66,9 +66,16 @@
// navigation - sort and filter bar // navigation - sort and filter bar
// -------------------------------- // --------------------------------
// Override global span rules // Override global label rules
.forum-nav-sort-label { .forum-nav-filter-main, .forum-nav-filter-cohort, .forum-nav-sort {
color: inherit; font: inherit;
line-height: 1em;
margin-bottom: 0;
}
// Override global select rules
.forum-nav-filter-main-control, .forum-nav-filter-cohort-control, .forum-nav-sort-control {
font: inherit;
} }
// -------------------------------- // --------------------------------
......
...@@ -20,18 +20,41 @@ ...@@ -20,18 +20,41 @@
<%include file="_filter_dropdown.html" /> <%include file="_filter_dropdown.html" />
<div class="forum-nav-thread-list-wrapper"> <div class="forum-nav-thread-list-wrapper">
<div class="forum-nav-refine-bar"> <div class="forum-nav-refine-bar">
<label class="forum-nav-filter-main">
## Translators: This labels a filter menu in forum navigation
<span class="sr">${_("Filter:")}</span>
<select class="forum-nav-filter-main-control">
## Translators: This is a menu option for showing all forum threads unfiltered
<option value="all">${_("Show all")}</option>
## Translators: This is a menu option for showing only unread forum threads
<option value="unread">${_("Unread")}</option>
## Translators: This is a menu option for showing only unanswered forum
## question threads
<option value="unanswered">${_("Unanswered")}</option>
%if flag_moderator:
## Translators: This is a menu option for showing only forum threads flagged
## for abuse
<option value="flagged">${_("Flagged")}</option>
%endif
</select>
</label>\
%if is_course_cohorted and is_moderator: %if is_course_cohorted and is_moderator:
<span class="forum-nav-filter-cohort"> ## Lack of indentation is intentional to avoid whitespace between this and siblings
<label class="forum-nav-filter-cohort">
## Translators: This labels a cohort menu in forum navigation
<span class="sr">${_("Cohort:")}</span>
<select class="forum-nav-filter-cohort-control"> <select class="forum-nav-filter-cohort-control">
<option value="all">${_("View all cohorts")}</option> <option value="all">${_("in all cohorts")}</option>
%for c in cohorts: %for c in cohorts:
<option value="${c['id']}">${_("View as {cohort_name}").format(cohort_name=c['name'])}</option> <option value="${c['id']}">${c['name']}</option>
%endfor %endfor
</select> </select>
</span> </label>\
%endif %endif
## Lack of indentation is intentional to avoid whitespace between this and siblings
<span class="forum-nav-sort"> <label class="forum-nav-sort">
## Translators: This labels a sort menu in forum navigation
<span class="sr">${_("Sort:")}</span>
<select class="forum-nav-sort-control"> <select class="forum-nav-sort-control">
## Translators: This is a menu option for sorting forum threads ## Translators: This is a menu option for sorting forum threads
<option value="date">${_("by recent activity")}</option> <option value="date">${_("by recent activity")}</option>
...@@ -40,7 +63,7 @@ ...@@ -40,7 +63,7 @@
## Translators: This is a menu option for sorting forum threads ## Translators: This is a menu option for sorting forum threads
<option value="votes">${_("by most votes")}</option> <option value="votes">${_("by most votes")}</option>
</select> </select>
</span> </label>
</div> </div>
<div class="search-alerts"></div> <div class="search-alerts"></div>
<ul class="forum-nav-thread-list"></ul> <ul class="forum-nav-thread-list"></ul>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment