Skip to content
Merged
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
35 changes: 34 additions & 1 deletion src/apps/api/serializers/competitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

from api.serializers.queues import QueueSerializer
from datetime import datetime
from django.utils.timezone import now


class PhaseSerializer(WritableNestedModelSerializer):
Expand Down Expand Up @@ -92,9 +93,10 @@ def validate_leaderboard(self, value):
class PhaseDetailSerializer(serializers.ModelSerializer):
tasks = PhaseTaskInstanceSerializer(source='task_instances', many=True)
status = serializers.SerializerMethodField()

public_data = DataDetailSerializer(read_only=True)
starting_kit = DataDetailSerializer(read_only=True)
used_submissions_per_day = serializers.SerializerMethodField()
used_submissions_per_person = serializers.SerializerMethodField()

class Meta:
model = Phase
Expand All @@ -117,6 +119,9 @@ class Meta:
'public_data',
'starting_kit',
'is_final_phase',
'used_submissions_per_day',
'used_submissions_per_person'

)

def get_status(self, obj):
Expand Down Expand Up @@ -155,6 +160,34 @@ def get_status(self, obj):
elif not phase_started:
return Phase.NEXT

def get_used_submissions_per_day(self, obj):

# Check if 'request' key exists in the context
if 'request' in self.context:
# Get user from the request
user = self.context['request'].user
if user.is_authenticated:
# Get all submissions which are not failed and belongs to this user for this phase
qs = obj.submissions.filter(owner=user, parent__isnull=True).exclude(status='Failed')
# Count submissions made today
daily_submission_count = qs.filter(created_when__day=now().day).count()
return daily_submission_count
return 0

def get_used_submissions_per_person(self, obj):

# Check if 'request' key exists in the context
if 'request' in self.context:
# Get user from the request
user = self.context['request'].user
if user.is_authenticated:
# Get all submissions which are not failed and belongs to this user for this phase
qs = obj.submissions.filter(owner=user, parent__isnull=True).exclude(status='Failed')
# Count all submissions
total_submission_count = qs.count()
return total_submission_count
return 0


class PhaseUpdateSerializer(PhaseSerializer):
tasks = PhaseTaskInstanceSerializer(source='task_instances', many=True)
Expand Down
1 change: 1 addition & 0 deletions src/static/riot/competitions/detail/_tabs.tag
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
</div>
</div>
<div>
<submission-limit></submission-limit>
<submission-upload is_admin="{competition.is_admin}" competition="{ competition }" phases="{ competition.phases }" fact_sheet="{ competition.fact_sheet }"></submission-upload>
</div>
<div>
Expand Down
94 changes: 94 additions & 0 deletions src/static/riot/competitions/detail/submission_limit.tag
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<submission-limit>
<div class="ui sixteen wide column submission-container">
<div class="col">
<div class="col-content">
Number of submissions used for the day
</div>
<span if="{selected_phase.max_submissions_per_day}" class="badge {badgeColor(selected_phase.used_submissions_per_day, selected_phase.max_submissions_per_day)}">
{selected_phase.used_submissions_per_day} out of {selected_phase.max_submissions_per_day}
</span>
</div>
<div class="col">
<div class="col-content">
Number of total submissions used
</div>
<span if="{selected_phase.max_submissions_per_person}" class="badge {badgeColor(selected_phase.used_submissions_per_person, selected_phase.max_submissions_per_person)}">
{selected_phase.used_submissions_per_person} out of {selected_phase.max_submissions_per_person}
</span>
</div>
</div>
<script>
var self = this;
self.selected_phase = {}

self.badgeColor = function(used, max) {

// Calculate the percentage of used submissions
var percentage = (used / max) * 100;

// Determine the badge color based on the percentage
if (percentage < 5) {
return "badge-green";
} else if (percentage < 25) {
return "badge-yellow";
} else if (percentage >= 25 && percentage < 50) {
return "badge-orange";
} else if (percentage >= 50 && percentage < 75) {
return "badge-pink";
} else {
return "badge-red";
}
};

CODALAB.events.on('phase_selected', function (selected_phase) {
self.selected_phase = selected_phase;
self.update();
});

</script>

<style type="text/stylus">
.submission-container
margin-top 1em
background-color white
padding 2em
border solid 1px #dcdcdcdc
display flex

.col
flex 1
display flex
flex-direction column
justify-content space-between

.col-content
font-weight bold
text-align center

.badge
padding 0.5em 1em
text-align center
display inline-block
width max-content
margin 0 auto
margin-top 0.5em
border-radius 5px

.badge-green
background-color #a5d6a7

.badge-yellow
background-color #fff59d

.badge-orange
background-color #ffcc80

.badge-pink
background-color #ff80ab

.badge-red
background-color #e57373


</style>
</submission-limit>