Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions src/apps/api/views/competitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def get_queryset(self):

qs = super().get_queryset()

# filter by competition_type first, 'competition' by default
# Filter by competition_type first, 'competition' by default
competition_type = self.request.query_params.get('type', Competition.COMPETITION)
if competition_type != 'any' and self.detail is False:
qs = qs.filter(competition_type=competition_type)
Expand Down Expand Up @@ -179,7 +179,8 @@ def get_queryset(self):
if search_query:
qs = qs.filter(Q(title__icontains=search_query) | Q(description__icontains=search_query))

qs = qs.order_by('created_when')
# Default sort
qs = qs.order_by('-created_when')
return qs

def get_permissions(self):
Expand Down Expand Up @@ -537,7 +538,20 @@ def create_dump(self, request, pk=None):
@action(detail=False, methods=('GET',), pagination_class=LargePagination)
def public(self, request):
qs = Competition.objects.filter(published=True)
qs = qs.order_by('-id')
# Grab `sort_by` and `has_reward` from query params
sort_by = self.request.query_params.get('sort_by', None)
has_reward = self.request.query_params.get('has_reward', 'false').lower()
# Filter for non-empty reward if "has_reward=true"
if has_reward in ['true', '1']:
qs = qs.exclude(reward__isnull=True).exclude(reward='')
# Sort based on `sort_by`
if sort_by == 'participants_count':
qs = qs.order_by('-participants_count') # e.g. descending
elif sort_by == 'submissions_count':
qs = qs.order_by('-submissions_count')
else:
# Default sort
qs = qs.order_by('-created_when')
queryset = self.filter_queryset(qs)
page = self.paginate_queryset(queryset)
if page is not None:
Expand Down
76 changes: 72 additions & 4 deletions src/static/riot/competitions/public-list.tag
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
<public-list>
<h1>Public Benchmarks and Competitions</h1>

<!-- Filter/Sort controls here -->
<div class="filters" style="margin: 15px 0;">
<label style="margin-right: 10px;">
<input type="checkbox" onclick="{toggleRewardFilter}" checked="{has_reward}">
Has reward
</label>
<label>
Sort by:
<select class="ui dropdown" onchange="{handleSort}">
<option value="created_when">Most Recent</option>
<option value="participants_count">Participants Count</option>
<option value="submissions_count">Submissions Count</option>
</select>
</label>
</div>

<div class="pagination-nav">
<button show="{competitions.previous}" onclick="{handle_ajax_pages.bind(this, -1)}" class="float-left ui inline button active">Back</button>
<button hide="{competitions.previous}" disabled="disabled" class="float-left ui inline button disabled">Back</button>
Expand Down Expand Up @@ -49,8 +66,30 @@
<script>
var self = this
self.competitions = {}
self.has_reward = false
self.sort_by = 'created_when'

function setUrlParams() {
let urlParams = new URLSearchParams(window.location.search);
urlParams.set("page", self.current_page);
urlParams.set("has_reward", self.has_reward);
urlParams.set("sort_by", self.sort_by);
history.pushState("", document.title, "?" + urlParams.toString());
}

self.one("mount", function () {
let urlParams = new URLSearchParams(window.location.search);
if(urlParams.has('sort_by')){
self.sort_by = urlParams.get('sort_by');
} else {
self.sort_by = 'created_when';
}
if(urlParams.has('has_reward')){
let val = urlParams.get('has_reward');
self.has_reward = (val === 'true' || val === '1');
} else {
self.has_reward = false;
}
self.update_competitions_list(self.get_url_page_number_or_default())
})

Expand All @@ -59,6 +98,18 @@
self.update_competitions_list(self.get_url_page_number_or_default() + num)
}

// Toggle has_reward, then reload
self.toggleRewardFilter = function (e) {
self.has_reward = e.target.checked
self.update_competitions_list(1)
}

// Update sort_by, then reload
self.handleSort = function (e) {
self.sort_by = e.target.value
self.update_competitions_list(self.current_page)
}

self.update_competitions_list = function (num) {
self.current_page = num;
$('#loading').show(); // Show the loading indicator
Expand All @@ -69,22 +120,25 @@
self.competitions = response;
$('#loading').hide(); // Hide the loading indicator
$('.pagination-nav').show(); // Show pagination navigation
history.pushState("", document.title, "?page=" + self.current_page);
$('.pagination-nav > button').prop('disabled', false);
//history.pushState("", document.title, "?page=" + self.current_page);
setUrlParams();
self.update();
}
// Fetch data using AJAX call
return CODALAB.api.get_public_competitions({"page": self.current_page})
return CODALAB.api.get_public_competitions({
"page": self.current_page,
"has_reward": self.has_reward,
"sort_by": self.sort_by
})
.fail(function (response) {
$('#loading').hide(); // Hide the loading indicator
$('.pagination-nav').show(); // Show pagination navigation
toastr.error("Could not load competition list");
})
.done(handleSuccess);

};


self.get_array_length = function (arr) {
if(arr === undefined){
return 0
Expand Down Expand Up @@ -122,6 +176,20 @@
}

$(window).on('popstate', function (event) {
// When the user clicks back/forward, parse the URL again
let urlParams = new URLSearchParams(window.location.search);
if(urlParams.has('sort_by')){
self.sort_by = urlParams.get('sort_by');
} else {
self.sort_by = 'created_when';
}
if(urlParams.has('has_reward')){
let val = urlParams.get('has_reward');
self.has_reward = (val === 'true' || val === '1');
} else {
self.has_reward = false;
}
// Then update page and re-fetch
self.update_competitions_list(self.get_url_page_number_or_default())
})

Expand Down