diff --git a/apps/jobs/views.py b/apps/jobs/views.py
index 29b4850da0..cef16b95d9 100644
--- a/apps/jobs/views.py
+++ b/apps/jobs/views.py
@@ -50,6 +50,7 @@
get_challenge_model,
get_challenge_phase_model,
get_challenge_phase_split_model,
+ get_participant_model,
)
from hosts.models import ChallengeHost
from hosts.utils import is_user_a_host_of_challenge
@@ -2824,7 +2825,35 @@ def update_submission_meta(request, challenge_pk, submission_pk):
serializer.errors, status=status.HTTP_400_BAD_REQUEST
)
else:
- response_data = {
- "error": "Sorry, you are not authorized to make this request"
- }
- return Response(response_data, status=status.HTTP_403_FORBIDDEN)
+ participant_team_pk = get_participant_team_id_of_user_for_a_challenge(
+ request.user, challenge_pk
+ )
+
+ participant_team = get_participant_model(participant_team_pk)
+
+ try:
+ submission = Submission.objects.get(
+ id=submission_pk,
+ participant_team=participant_team,
+ )
+ except Submission.DoesNotExist:
+ response_data = {
+ "error": "Submission {} does not exist".format(submission_pk)
+ }
+ return Response(response_data, status=status.HTTP_404_NOT_FOUND)
+
+ serializer = SubmissionSerializer(
+ submission,
+ data=request.data,
+ context={"request": request},
+ partial=True,
+ )
+
+ if serializer.is_valid():
+ serializer.save()
+ response_data = serializer.data
+ return Response(response_data, status=status.HTTP_200_OK)
+ else:
+ return Response(
+ serializer.errors, status=status.HTTP_400_BAD_REQUEST
+ )
diff --git a/frontend/src/js/controllers/challengeCtrl.js b/frontend/src/js/controllers/challengeCtrl.js
index ff58821393..8fbce15eb1 100644
--- a/frontend/src/js/controllers/challengeCtrl.js
+++ b/frontend/src/js/controllers/challengeCtrl.js
@@ -2030,7 +2030,44 @@
}
};
- vm.hideVisibilityDialog = function() {
+ vm.cancelSubmission = function(submissionId) {
+ parameters.url = "jobs/challenges/" + vm.challengeId + "/submissions/" + submissionId + "/update_submission_meta/";
+ parameters.method = 'PATCH';
+ parameters.data = {
+ "status": "cancelled",
+ };
+ parameters.callback = {
+ onSuccess: function(response) {
+ var status = response.status;
+ if (status === 200) {
+ $mdDialog.hide();
+ $rootScope.notify("success", "Submission cancelled successfully!");
+ }
+ },
+ onError: function(response) {
+ $mdDialog.hide();
+ var error = response.data;
+ $rootScope.notify("error", error);
+ }
+ };
+
+ utilities.sendRequest(parameters);
+ };
+
+ vm.showCancelSubmissionDialog = function(submissionId, status) {
+ if (status != "submitted") {
+ $rootScope.notify("error", "Only unproccessed submissions can be cancelled");
+ return;
+ }
+ vm.submissionId = submissionId;
+ $mdDialog.show({
+ scope: $scope,
+ preserveScope: true,
+ templateUrl: 'dist/views/web/challenge/cancel-submission.html'
+ });
+ };
+
+ vm.hideDialog = function() {
$mdDialog.hide();
};
diff --git a/frontend/src/views/web/challenge/cancel-submission.html b/frontend/src/views/web/challenge/cancel-submission.html
new file mode 100644
index 0000000000..5b6370963a
--- /dev/null
+++ b/frontend/src/views/web/challenge/cancel-submission.html
@@ -0,0 +1,16 @@
+