Skip to content

Commit e8850e7

Browse files
Add homework submission editing with enrollment quick access and clear buttons (#152)
* Initial plan * Add homework submission edit functionality Co-authored-by: alexeygrigorev <875246+alexeygrigorev@users.noreply.github.com> * Add submission edit links to enrollment page and clear LiP buttons Co-authored-by: alexeygrigorev <875246+alexeygrigorev@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: alexeygrigorev <875246+alexeygrigorev@users.noreply.github.com>
1 parent f322303 commit e8850e7

7 files changed

Lines changed: 630 additions & 2 deletions

File tree

cadmin/templates/cadmin/enrollment_edit.html

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,82 @@ <h3>Learning in Public Control</h3>
117117
</div>
118118
</div>
119119

120+
<div class="card my-4">
121+
<div class="card-header">
122+
<h3>Homework Submissions</h3>
123+
</div>
124+
<div class="card-body">
125+
{% if homework_submissions %}
126+
<div class="table-responsive">
127+
<table class="table table-striped table-hover">
128+
<thead>
129+
<tr>
130+
<th>Homework</th>
131+
<th>Submitted</th>
132+
<th>Score</th>
133+
<th>Actions</th>
134+
</tr>
135+
</thead>
136+
<tbody>
137+
{% for submission in homework_submissions %}
138+
<tr>
139+
<td>{{ submission.homework.title }}</td>
140+
<td>{{ submission.submitted_at|date:"Y-m-d H:i" }}</td>
141+
<td>{{ submission.total_score }}</td>
142+
<td>
143+
<a href="{% url 'cadmin_homework_submission_edit' course.slug submission.homework.slug submission.id %}" class="btn btn-sm btn-primary">
144+
<i class="fas fa-edit"></i> Edit
145+
</a>
146+
</td>
147+
</tr>
148+
{% endfor %}
149+
</tbody>
150+
</table>
151+
</div>
152+
{% else %}
153+
<p class="text-muted">No homework submissions yet.</p>
154+
{% endif %}
155+
</div>
156+
</div>
157+
158+
<div class="card my-4">
159+
<div class="card-header">
160+
<h3>Project Submissions</h3>
161+
</div>
162+
<div class="card-body">
163+
{% if project_submissions %}
164+
<div class="table-responsive">
165+
<table class="table table-striped table-hover">
166+
<thead>
167+
<tr>
168+
<th>Project</th>
169+
<th>Submitted</th>
170+
<th>Score</th>
171+
<th>Actions</th>
172+
</tr>
173+
</thead>
174+
<tbody>
175+
{% for submission in project_submissions %}
176+
<tr>
177+
<td>{{ submission.project.title }}</td>
178+
<td>{{ submission.submitted_at|date:"Y-m-d H:i" }}</td>
179+
<td>{{ submission.total_score }}</td>
180+
<td>
181+
<a href="{% url 'cadmin_project_submission_edit' course.slug submission.project.slug submission.id %}" class="btn btn-sm btn-primary">
182+
<i class="fas fa-edit"></i> Edit
183+
</a>
184+
</td>
185+
</tr>
186+
{% endfor %}
187+
</tbody>
188+
</table>
189+
</div>
190+
{% else %}
191+
<p class="text-muted">No project submissions yet.</p>
192+
{% endif %}
193+
</div>
194+
</div>
195+
120196
<div class="my-4">
121197
<a href="{% url 'leaderboard_score_breakdown' course_slug=course.slug enrollment_id=enrollment.id %}" class="btn btn-secondary">View Score Breakdown</a>
122198
<a href="{% url 'leaderboard' course.slug %}" class="btn btn-secondary">View Leaderboard</a>
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
{% extends 'cadmin/base.html' %}
2+
3+
{% load custom_filters %}
4+
5+
{% block breadcrumbs %}
6+
<li><a href="{% url 'cadmin_course_list' %}">Course Admin</a></li>
7+
<li><a href="{% url 'cadmin_course' course.slug %}">{{ course.title }}</a></li>
8+
<li><a href="{% url 'cadmin_homework_submissions' course.slug homework.slug %}">{{ homework.title }} Submissions</a></li>
9+
<li><a href="{% url 'cadmin_homework_submission_edit' course.slug homework.slug submission.id %}">Edit Submission</a></li>
10+
{% endblock %}
11+
12+
{% block cadmin_content %}
13+
<h2>Edit Homework Submission</h2>
14+
15+
<div class="mb-3">
16+
<a href="{% url 'cadmin_homework_submissions' course.slug homework.slug %}" class="btn btn-secondary">Back to Submissions</a>
17+
</div>
18+
19+
<div class="alert alert-info" role="alert">
20+
<strong>Student:</strong> {{ submission.student.username }} ({{ submission.student.email }})<br>
21+
<strong>Homework:</strong> {{ homework.title }}<br>
22+
<strong>Submitted:</strong> {{ submission.submitted_at|date:"Y-m-d H:i" }}<br>
23+
<strong>Current Total Score:</strong> {{ submission.total_score }}
24+
</div>
25+
26+
<form method="post">
27+
{% csrf_token %}
28+
29+
<div class="card mb-3">
30+
<div class="card-header">
31+
<h4>Question Answers</h4>
32+
</div>
33+
<div class="card-body">
34+
{% if questions_with_answers %}
35+
{% for item in questions_with_answers %}
36+
<div class="card mb-3 border-secondary">
37+
<div class="card-header bg-light">
38+
<strong>Question {{ forloop.counter }}:</strong> {{ item.question.text }}
39+
</div>
40+
<div class="card-body">
41+
<div class="mb-2">
42+
<strong>Question Type:</strong> {{ item.question.get_question_type_display }}<br>
43+
{% if item.question.correct_answer %}
44+
<strong>Correct Answer:</strong> {{ item.question.correct_answer }}
45+
{% endif %}
46+
</div>
47+
48+
{% if item.question.question_type == "MC" %}
49+
{# Multiple choice question #}
50+
<div class="form-group">
51+
<label for="answer_{{ item.question.id }}">Answer (option number):</label>
52+
<input type="text"
53+
class="form-control"
54+
id="answer_{{ item.question.id }}"
55+
name="answer_{{ item.question.id }}"
56+
value="{{ item.answer_text }}"
57+
placeholder="Enter option number">
58+
{% if item.question.possible_answers %}
59+
<small class="form-text text-muted">
60+
Options:
61+
{% for option in item.question.get_possible_answers %}
62+
{{ forloop.counter }}. {{ option }}{% if not forloop.last %}, {% endif %}
63+
{% endfor %}
64+
</small>
65+
{% endif %}
66+
</div>
67+
{% elif item.question.question_type == "CB" %}
68+
{# Checkbox question #}
69+
<div class="form-group">
70+
<label for="answer_{{ item.question.id }}">Answer (comma-separated option numbers):</label>
71+
<input type="text"
72+
class="form-control"
73+
id="answer_{{ item.question.id }}"
74+
name="answer_{{ item.question.id }}"
75+
value="{{ item.answer_text }}"
76+
placeholder="e.g., 1,3,4">
77+
{% if item.question.possible_answers %}
78+
<small class="form-text text-muted">
79+
Options:
80+
{% for option in item.question.get_possible_answers %}
81+
{{ forloop.counter }}. {{ option }}{% if not forloop.last %}, {% endif %}
82+
{% endfor %}
83+
</small>
84+
{% endif %}
85+
</div>
86+
{% elif item.question.question_type == "FL" %}
87+
{# Free form long #}
88+
<div class="form-group">
89+
<label for="answer_{{ item.question.id }}">Answer:</label>
90+
<textarea class="form-control"
91+
id="answer_{{ item.question.id }}"
92+
name="answer_{{ item.question.id }}"
93+
rows="4">{{ item.answer_text }}</textarea>
94+
</div>
95+
{% else %}
96+
{# Free form or other #}
97+
<div class="form-group">
98+
<label for="answer_{{ item.question.id }}">Answer:</label>
99+
<input type="text"
100+
class="form-control"
101+
id="answer_{{ item.question.id }}"
102+
name="answer_{{ item.question.id }}"
103+
value="{{ item.answer_text }}">
104+
</div>
105+
{% endif %}
106+
107+
{% if item.answer %}
108+
<div class="mt-2">
109+
<span class="badge {% if item.answer.is_correct %}badge-success{% else %}badge-danger{% endif %}">
110+
{% if item.answer.is_correct %}Correct{% else %}Incorrect{% endif %}
111+
</span>
112+
</div>
113+
{% endif %}
114+
</div>
115+
</div>
116+
{% endfor %}
117+
{% else %}
118+
<p class="text-muted">No questions found for this homework.</p>
119+
{% endif %}
120+
</div>
121+
</div>
122+
123+
<div class="card mb-3">
124+
<div class="card-header">
125+
<h4>Learning in Public Links</h4>
126+
</div>
127+
<div class="card-body">
128+
<div class="form-group">
129+
<label for="learning_in_public_links">Links (comma-separated):</label>
130+
<textarea class="form-control"
131+
id="learning_in_public_links"
132+
name="learning_in_public_links"
133+
rows="3"
134+
placeholder="https://example.com/post1, https://example.com/post2">{% if submission.learning_in_public_links %}{{ submission.learning_in_public_links|join:", " }}{% endif %}</textarea>
135+
<small class="form-text text-muted">
136+
Enter URLs separated by commas. Each link contributes to the learning in public score (capped at {{ homework.learning_in_public_cap }}).
137+
</small>
138+
</div>
139+
<button type="button" class="btn btn-warning" id="clear-lip-links" onclick="clearLearningInPublicLinks()">
140+
<i class="fas fa-trash"></i> Remove Learning in Public Links
141+
</button>
142+
</div>
143+
</div>
144+
145+
<script>
146+
function clearLearningInPublicLinks() {
147+
if (confirm('Are you sure you want to remove all learning in public links for this submission? This will set the learning in public score to 0.')) {
148+
document.getElementById('learning_in_public_links').value = '';
149+
}
150+
}
151+
</script>
152+
153+
<div class="card mb-3">
154+
<div class="card-header">
155+
<h4>Current Scores (Read-Only)</h4>
156+
</div>
157+
<div class="card-body">
158+
<div class="row">
159+
<div class="col-md-3">
160+
<div class="form-group">
161+
<label>Questions Score</label>
162+
<input type="text" class="form-control" value="{{ submission.questions_score }}" readonly>
163+
</div>
164+
</div>
165+
<div class="col-md-3">
166+
<div class="form-group">
167+
<label>FAQ Score</label>
168+
<input type="text" class="form-control" value="{{ submission.faq_score }}" readonly>
169+
</div>
170+
</div>
171+
<div class="col-md-3">
172+
<div class="form-group">
173+
<label>Learning in Public Score</label>
174+
<input type="text" class="form-control" value="{{ submission.learning_in_public_score }}" readonly>
175+
</div>
176+
</div>
177+
<div class="col-md-3">
178+
<div class="form-group">
179+
<label>Total Score</label>
180+
<input type="text" class="form-control" value="{{ submission.total_score }}" readonly>
181+
</div>
182+
</div>
183+
</div>
184+
<small class="form-text text-muted">
185+
Scores will be automatically recalculated when you save. If the total score changes, the leaderboard will be updated.
186+
</small>
187+
</div>
188+
</div>
189+
190+
<div class="text-center">
191+
<button type="submit" class="btn btn-primary">Save Changes</button>
192+
<a href="{% url 'cadmin_homework_submissions' course.slug homework.slug %}" class="btn btn-secondary">Cancel</a>
193+
</div>
194+
</form>
195+
196+
{% endblock %}

cadmin/templates/cadmin/homework_submissions.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ <h2>{{ homework.title }} - Submissions</h2>
7070
</td>
7171
{% endfor %}
7272
<td>
73+
<a href="{% url 'cadmin_homework_submission_edit' course.slug homework.slug data.submission.id %}"
74+
class="btn btn-sm btn-primary"
75+
title="Edit submission">
76+
<i class="fas fa-edit"></i> Edit
77+
</a>
7378
<form method="post" action="{% url 'loginas-user-login' data.submission.student.id %}" style="display: inline;">
7479
{% csrf_token %}
7580
<input type="hidden" name="next" value="{% url 'cadmin_homework_submissions' course.slug homework.slug %}">

cadmin/templates/cadmin/project_submission_edit.html

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ <h4>Additional Project Scores</h4>
8484
<div class="form-group mb-3">
8585
<label for="project_learning_in_public_score">Project Learning in Public Score</label>
8686
<input type="number" class="form-control additional-score" id="project_learning_in_public_score" name="project_learning_in_public_score" value="{{ submission.project_learning_in_public_score }}" required>
87+
<button type="button" class="btn btn-sm btn-warning mt-2" onclick="clearProjectLearningInPublicScore()">
88+
<i class="fas fa-trash"></i> Remove Project Learning in Public Score
89+
</button>
8790
</div>
8891
</div>
8992
</div>
@@ -101,6 +104,9 @@ <h4>Peer Review Scores</h4>
101104
<div class="form-group mb-3">
102105
<label for="peer_review_learning_in_public_score">Peer Review Learning in Public Score</label>
103106
<input type="number" class="form-control peer-review-score" id="peer_review_learning_in_public_score" name="peer_review_learning_in_public_score" value="{{ submission.peer_review_learning_in_public_score }}" required>
107+
<button type="button" class="btn btn-sm btn-warning mt-2" onclick="clearPeerReviewLearningInPublicScore()">
108+
<i class="fas fa-trash"></i> Remove Peer Review Learning in Public Score
109+
</button>
104110
</div>
105111
</div>
106112
</div>
@@ -220,6 +226,22 @@ <h4>Overall Results</h4>
220226
// Calculate initial values
221227
calculateTotal();
222228
});
229+
230+
function clearProjectLearningInPublicScore() {
231+
if (confirm('Are you sure you want to remove the project learning in public score? This will set it to 0.')) {
232+
document.getElementById('project_learning_in_public_score').value = '0';
233+
// Trigger recalculation
234+
document.getElementById('project_learning_in_public_score').dispatchEvent(new Event('input'));
235+
}
236+
}
237+
238+
function clearPeerReviewLearningInPublicScore() {
239+
if (confirm('Are you sure you want to remove the peer review learning in public score? This will set it to 0.')) {
240+
document.getElementById('peer_review_learning_in_public_score').value = '0';
241+
// Trigger recalculation
242+
document.getElementById('peer_review_learning_in_public_score').dispatchEvent(new Event('input'));
243+
}
244+
}
223245
</script>
224246

225247
{% endblock %}

0 commit comments

Comments
 (0)