Skip to content
......@@ -9,4 +9,4 @@ Welcome, and we hope you have a productive class!{% endblocktrans %}
One common reason for this may be that you may have used your personal email (such as a GMail or Yahoo account) rather than your official university account to sign in. If that is the case, please use the official account and try again.{% endblocktrans %}
{% endif %}
{% blocktrans %}- RELATE staff {% endblocktrans %}
- {% blocktrans %}{{ relate_site_name }} staff{% endblocktrans %}
......@@ -5,4 +5,4 @@ User '{{user}}' has requested permission to enroll in your course. Please go to
to approve or deny the request. To do so, select the course participations in question and use the "Approve enrollment" or "Deny enrollment" admin
actions.
{% endblocktrans %}
{% blocktrans %}- RELATE staff {% endblocktrans %}
\ No newline at end of file
- {% blocktrans %}{{ relate_site_name }} staff{% endblocktrans %}
\ No newline at end of file
......@@ -7,7 +7,7 @@
<h1>{% trans "Check in for Exam" %}</h1>
<div class="alert alert-info">
<i class="fa fa-chevron-left"></i>
<i class="bi bi-chevron-left"></i>
{% url "relate-sign_in_choice" as relate-sign_in_choice %}
{% blocktrans trimmed %}
If you have a not been issued an exam ticket by your instructor,
......@@ -16,7 +16,7 @@
instead.
{% endblocktrans %}
</div>
<div class="well">
<div class="relate-well">
{% crispy form %}
</div>
{% endblock %}
......@@ -4,7 +4,7 @@
<div class="panel-heading">{% trans "Overall grade" %}</div>
<div class="panel-body">
<p><b>
{% blocktrans trimmed with percentage=percentage|floatformat %}
{% blocktrans trimmed with percentage=percentage|floatformat:"-2" %}
The overall grade is {{ percentage }}%.
{% endblocktrans %}
</b></p>
......@@ -17,7 +17,7 @@
<div class="panel-body">
{% if code_feedback.percentage != None %}
<p><b>
{% blocktrans trimmed with feedback_points=code_feedback_points|floatformat points=code_points|floatformat %}
{% blocktrans trimmed with feedback_points=code_feedback_points|floatformat:"-2" points=code_points|floatformat:"-2" %}
The autograder assigned {{ feedback_points }}/{{ points }} points.
{% endblocktrans %}
</b>
......@@ -34,7 +34,7 @@
<div class="panel-body">
{% if human_feedback_points != None %}
<p><b>
{% blocktrans trimmed with feedback_points=human_feedback_points|floatformat human_points=human_points|floatformat %}
{% blocktrans trimmed with feedback_points=human_feedback_points|floatformat:"-2" human_points=human_points|floatformat:"-2" %}
The human grader assigned {{ feedback_points }}/{{ human_points }} points.
{% endblocktrans %}
</b></p>
......
......@@ -5,52 +5,11 @@
<div id="file_upload_viewer_div">
</div>
<div class="col-lg-offset-2" style="margin-bottom:2ex">
<a href="{{ data_url }}" id="file_upload_download_link">{% trans "Review uploaded file" %}</a>
&middot;
<a href="javascript:file_upload_embed_viewer()">{% trans "Embed viewer" %}</a>
<a href="{{ data_url }}" id="file_upload_download_link" target="_blank">{% trans "Download/review uploaded file in new window" %}</a>
</div>
<script type="text/javascript">
function file_upload_embed_viewer()
{
var data_url = $("#file_upload_download_link").attr("href");
$("#file_upload_viewer_div").html(
"<object data='" + data_url + "' type='{{ mime_type }}' width='100%' height='800px' align='middle'>"
+ '<p>('
+ "{% blocktrans %} Your browser reported itself unable to render <tt>{{ mime_type }}</tt> inline. {% endblocktrans %}"
+ ')</p>'
+ '</object><hr>');
}
function file_upload_data_url_to_object_url() {
// https://code.google.com/p/chromium/issues/detail?id=69227#37
var is_webkit = /WebKit/.test(navigator.userAgent);
if (is_webkit)
{
var data_url = $("#file_upload_download_link").attr("href");
//take apart data URL
var parts = data_url.match(/data:([^;]*)(;base64)?,([0-9A-Za-z+/]+)/);
//assume base64 encoding
var binStr = atob(parts[3]);
//convert to binary in ArrayBuffer
var buf = new ArrayBuffer(binStr.length);
var view = new Uint8Array(buf);
for(var i = 0; i < view.length; i++)
view[i] = binStr.charCodeAt(i);
var blob = new Blob([view], {'type': parts[1]});
var obj_url = webkitURL.createObjectURL(blob)
$("#file_upload_download_link").attr("href", obj_url);
}
}
file_upload_data_url_to_object_url()
$(document).ready(rlUtils.enablePreviewForFileUpload);
</script>
{% endif %}
......
......@@ -3,87 +3,110 @@
{% load i18n %}
{% block title %}
{{flow_desc.title}} - {% trans "RELATE" %}
{{flow_desc.title}} - {{ relate_site_name }}
{% endblock %}
{% block content %}
{% if grade_info != None and grade_info.total_count %}
<h1>{% trans "Results" %}: {{flow_desc.title}}</h1>
<div class="well flow-well">
<p>
{# Translators: the following 5 blocks of literals make a sentence. PartI #}
{% trans "You have" %}
{% if grade_info.max_points != grade_info.max_reachable_points %}
{# Translators: PartII #}
<b>{% trans "(so far)" %}</b>
{% endif %}
{# Translators: PartIII #}
{% blocktrans trimmed with provisional_points=grade_info.provisional_points|floatformat max_points=grade_info.max_points|floatformat %}
achieved <b>{{ provisional_points }}</b> out of
{{ max_points }}
points.
{% endblocktrans %}
{% if grade_info.max_points != grade_info.max_reachable_points %}
{# Translators: PartIV #}
{% blocktrans trimmed %}
(Some questions are not graded yet, so your grade will likely
change.)
{% endblocktrans %}
{% else %}
{# Translators: PartV #}
{% blocktrans trimmed with points_percent=grade_info.points_percent|floatformat %}
(That's <b>{{ points_percent }}%</b>.)
{% endblocktrans %}
{% endif %}
</p>
{% if grade_info.total_points_percent < 100.001 %}
{# otherwise we'll have trouble drawing the bar #}
<div class="progress">
<div class="progress-bar progress-bar-success"
style="width: {{ grade_info.points_percent|stringformat:".8f" }}%"></div>
<div class="progress-bar progress-bar-danger"
style="width: {{ grade_info.missed_points_percent|stringformat:".8f" }}%"></div>
<div class="progress-bar progress-bar-info"
style="width: {{ grade_info.unreachable_points_percent|stringformat:".8f" }}%"></div>
</div>
{% endif %}
<p>
{% blocktrans trimmed with fully_correct_count=grade_info.fully_correct_count partially_correct_count=grade_info.partially_correct_count incorrect_count=grade_info.incorrect_count %}
You have answered {{ fully_correct_count }} questions
correctly, {{ partially_correct_count }} questions
partially correctly, and {{ incorrect_count }} questions
incorrectly.
{% endblocktrans %}
{% if grade_info.unknown_count %}
{% blocktrans trimmed with unknown_count=grade_info.unknown_count %}
The grade for {{ unknown_count }} questions is not yet known.
{% endblocktrans %}
{% endif %}
</p>
<div class="progress">
<div class="progress-bar progress-bar-success"
style="width: {{ grade_info.fully_correct_percent|stringformat:".8f" }}%"></div>
<div class="progress-bar progress-bar-warning"
style="width: {{ grade_info.partially_correct_percent|stringformat:".8f" }}%"></div>
<div class="progress-bar progress-bar-danger"
style="width: {{ grade_info.incorrect_percent|stringformat:".8f" }}%"></div>
<div class="progress-bar progress-bar-info"
style="width: {{ grade_info.unknown_percent|stringformat:".8f" }}%"></div>
</div>
</div>
{% if grade_info != None %}
{% if grade_info.total_count or grade_info.optional_total_count %}
<h1>{% trans "Results" %}: {{flow_desc.title}}</h1>
<div class="relate-well flow-well">
{% if grade_info.total_count %}
<p>
{# Translators: the following 5 blocks of literals make a sentence. PartI #}
{% trans "You have" %}
{% if grade_info.max_points != grade_info.max_reachable_points %}
{# Translators: PartII #}
<b>{% trans "(so far)" %}</b>
{% endif %}
{# Translators: PartIII #}
{% blocktrans trimmed with provisional_points=grade_info.provisional_points|floatformat:"-2" max_points=grade_info.max_points|floatformat:"-2" %}
achieved <b>{{ provisional_points }}</b> out of
{{ max_points }}
points.
{% endblocktrans %}
{% if grade_info.max_points != grade_info.max_reachable_points %}
{# Translators: PartIV #}
{% blocktrans trimmed %}
(Some questions are not graded yet, so your grade will likely
change.)
{% endblocktrans %}
{% else %}
{# Translators: PartV #}
{% blocktrans trimmed with points_percent=grade_info.points_percent|floatformat:"-2" %}
(That's <b>{{ points_percent }}%</b>.)
{% endblocktrans %}
{% endif %}
</p>
{% if grade_info.total_points_percent < 100.001 %}
{# otherwise we'll have trouble drawing the bar #}
<div class="progress">
<div class="progress-bar bg-success"
style="width: {{ grade_info.points_percent|stringformat:".8f" }}%"></div>
<div class="progress-bar bg-danger"
style="width: {{ grade_info.missed_points_percent|stringformat:".8f" }}%"></div>
<div class="progress-bar bg-info"
style="width: {{ grade_info.unreachable_points_percent|stringformat:".8f" }}%"></div>
</div>
{% endif %}
<p>
{% blocktrans trimmed with fully_correct_count=grade_info.fully_correct_count partially_correct_count=grade_info.partially_correct_count incorrect_count=grade_info.incorrect_count %}
You have answered {{ fully_correct_count }} grading questions
correctly, {{ partially_correct_count }} questions
partially correctly, and {{ incorrect_count }} questions
incorrectly.
{% endblocktrans %}
{% if grade_info.unknown_count %}
{% blocktrans trimmed with unknown_count=grade_info.unknown_count %}
The grade for {{ unknown_count }} questions is not yet known.
{% endblocktrans %}
{% endif %}
</p>
<div class="progress">
<div class="progress-bar bg-success"
style="width: {{ grade_info.fully_correct_percent|stringformat:".8f" }}%"></div>
<div class="progress-bar bg-warning"
style="width: {{ grade_info.partially_correct_percent|stringformat:".8f" }}%"></div>
<div class="progress-bar bg-danger"
style="width: {{ grade_info.incorrect_percent|stringformat:".8f" }}%"></div>
<div class="progress-bar bg-info"
style="width: {{ grade_info.unknown_percent|stringformat:".8f" }}%"></div>
</div>
{% endif %}
{% if grade_info.optional_total_count %}
<p>
{% blocktrans trimmed with total_count=grade_info.optional_total_count fully_correct_count=grade_info.optional_fully_correct_count partially_correct_count=grade_info.optional_partially_correct_count incorrect_count=grade_info.optional_incorrect_count %}
There are {{ total_count }} optional questions (not for grading).
You have answered {{ fully_correct_count }} correctly,
{{ partially_correct_count }} partially correctly,
and {{ incorrect_count }} incorrectly.
{% endblocktrans %}
{% if grade_info.optional_unknown_count %}
{% blocktrans trimmed with unknown_count=grade_info.optional_unknown_count %}
The correctness for {{ unknown_count }} optional questions is not yet known.
{% endblocktrans %}
{% endif %}
</p>
<div class="progress">
<div class="progress-bar bg-success"
style="width: {{ grade_info.optional_fully_correct_percent|stringformat:".8f" }}%"></div>
<div class="progress-bar bg-warning"
style="width: {{ grade_info.optional_partially_correct_percent|stringformat:".8f" }}%"></div>
<div class="progress-bar bg-danger"
style="width: {{ grade_info.optional_incorrect_percent|stringformat:".8f" }}%"></div>
<div class="progress-bar bg-info"
style="width: {{ grade_info.optional_unknown_percent|stringformat:".8f" }}%"></div>
</div>
{% endif %}
</div>
{% endif %}
{% endif %}
{{ completion_text|safe }}
<div class="well flow-well">
<a class="btn btn-default"
href="{% url "relate-view_start_flow" course.identifier flow_identifier %}"
role="button">&laquo; {% trans "Back to start page" %}</a>
</div>
<a class="btn btn-secondary"
href="{% url "relate-view_start_flow" course.identifier flow_identifier %}"
role="button">&laquo; {% trans "Back to start page" %}</a>
{% endblock %}
......@@ -3,16 +3,14 @@
{% load i18n %}
{% block title %}
{{flow_desc.title}} - {% trans "RELATE" %}
{{flow_desc.title}} - {{ relate_site_name }}
{% endblock %}
{% block content %}
{{ completion_text|safe }}
<div class="well flow-well">
<a class="btn btn-default"
href="{% url "relate-view_start_flow" course.identifier flow_identifier %}"
role="button">&laquo; {% trans "Back to start page" %}</a>
</div>
<a class="btn btn-secondary"
href="{% url "relate-view_start_flow" course.identifier flow_identifier %}"
role="button">&laquo; {% trans "Back to start page" %}</a>
{% endblock %}
......@@ -3,7 +3,7 @@
{% load i18n %}
{% block title %}
{{flow_desc.title}} - {% trans "RELATE" %}
{{flow_desc.title}} - {{ relate_site_name }}
{% endblock %}
{% block content %}
......@@ -11,15 +11,15 @@
{% if unanswered_count %}
<div class="alert alert-danger">
<i class="fa fa-warning"></i>
<i class="bi bi-exclamation-triangle"></i>
{% trans "You have left the following question(s) unanswered:" %}
<ul>
{% for page_data in unanswered_page_data_list %}
<li>
<a href="{% url "relate-view_flow_page" course.identifier flow_session.id page_data.ordinal %}">
{{ page_data.human_readable_ordinal }}: {{ page_data.title }}
<a href="{% url "relate-view_flow_page" course.identifier flow_session.id page_data.page_ordinal %}">
{{ page_data.human_readable_ordinal }}: {{ page_data.title|safe }}
{% if page_data.bookmarked %}
<i class="fa fa-star" aria-hidden="true"></i>
<i class="bi bi-star-filled" aria-hidden="true"></i>
{% endif %}
</a>
</li>
......@@ -28,12 +28,12 @@
</div>
{% endif %}
{% if total_count %}
{% if required_count %}
<p>
{% blocktrans trimmed %}
There were {{total_count}} questions.
There were {{required_count}} grading questions.
{% endblocktrans %}
{% if answered_count == total_count %}
{% if answered_count == required_count %}
{% blocktrans trimmed %}
You have provided an answer for all of them.
{% endblocktrans %}
......@@ -48,15 +48,17 @@
{% trans "If you choose to end your session, the following things will happen:" %}
<ul>
<li>{% trans "You will be prevented from making further changes to your answers." %}</li>
<li>{% trans "All your currently saved answers, if not graded already, will be graded." %}</li>
<li>{% trans "If possible, a final grade will be computed from all saved, graded answers." %}</li>
{% if session_may_generate_grade %}
<li>{% trans "All your currently saved answers, if not graded already, will be graded." %}</li>
<li>{% trans "If possible, a final grade will be computed from all saved, graded answers." %}</li>
{% endif %}
</ul>
<div class="well flow-well">
<div class="relate-well flow-well">
<form method="POST" id="submit-form">
{% csrf_token %}
<a class="btn btn-default"
<a class="btn btn-secondary"
href="{% url "relate-view_flow_page" course.identifier flow_session.id last_page_nr %}"
role="button">&laquo; {% trans "Go back" %}</a>
......@@ -66,12 +68,12 @@
</a>
<button id="submit" type="submit" name="submit" class="btn btn-danger"
style="display:none"
data-content='<p>{% trans "Are you sure you will submit this session with questions unanswered?" %}</p>
<button id="cancel-button" type="reset" name="cancel" class="btn btn-primary btn-sm" style="float: right;">
data-bs-content='<p>{% trans "Are you sure you would like to submit this session with questions unanswered?" %}</p>
<a href="#" id="cancel-button" class="btn btn-primary btn-sm">
{% trans "Cancel" %}</button>'
data-html="true"
data-container="body"
data-placement="right"
data-bs-html="true"
data-bs-container="body"
data-bs-placement="right"
>
{% trans "I am sure" %} &raquo;
</button>
......
{% load i18n %}
{% if not prev_answer_visits %}
<li><h6 class="dropdown-header">{% trans 'No submission history' %}</h6> </li>
{% else %}
{% for visit in prev_answer_visits %}
<li>
{% if forloop.first %}
<a class="dropdown-item" href="?">
{% else %}
<a class="dropdown-item" href="?visit_id={{ visit.id }}">
{% endif %}
{% if visit.id == prev_visit_id %}<b>{% endif %}
{{ visit.visit_time }}
{% if forloop.first %}(current){% endif %}
{% if visit.id == prev_visit_id %}</b>{% endif %}
{% if visit.is_submitted_answer %}(submitted){% endif %}
</a>
</li>
{% endfor %}
{% endif %}
{% extends "course/course-base.html" %}
{% extends "course/course-base-with-markup.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
......@@ -6,286 +6,308 @@
{% block title %}
[{{ page_data.next_ordinal }}/{{ flow_session.page_count }}]
{{title}} - {{ flow_desc.title}} - {% trans "RELATE" %}
{{title|safe}} - {{ flow_desc.title}} - {{ relate_site_name }}
{% endblock %}
{% block content %}
{% if user != flow_session.participation.user %}
<div id="other-user-alert" class="alert alert-info">
<div style="float:right">
<a onclick='$("#other-user-alert").hide()'>
<i class="bi bi-x-circle" aria-hidden="true"></i><Paste>
</a>
</div>
<i class="bi bi-person" aria-hidden="true"></i>
{% trans "Viewing session for participant" %}
{% if flow_session.participation != None %}
<a href="{% url "relate-view_participant_grades" course.identifier flow_session.participation.id %}">{% if not pperm.view_participant_masked_profile %}{{ flow_session.participation.user.username }}{% else %}{{ flow_session.participation.user.get_masked_profile }}{% endif %}</a>.
{% else %}
{% trans "(unspecified participant)" %}.
{% endif %}
</div>
{% endif %}
{# {{{ navigation #}
<form
action="{% url "relate-view_flow_page" course.identifier flow_session.id page_data.ordinal %}"
action="{% url "relate-view_flow_page" course.identifier flow_session.id page_data.page_ordinal %}"
class="navigation-form"
method="POST">
{% csrf_token %}
<div class="well flow-well">
{# {{{ prev/next buttons #}
<div class="flow-nav">
{% if page_data.ordinal > 0 %}
<a class="btn btn-default relate-nav-button"
href="{% url "relate-view_flow_page" course.identifier flow_session.id page_data.previous_ordinal %}"
title='{% trans "Previous page" context "Previous page/item in a flow" %}'
role="button"><i class="fa fa-chevron-left"></i></a>
{% else %}
<a class="btn btn-default relate-nav-button disabled"
href="#"
title='{% trans "Previous page" context "Previous page/item in a flow" %}'
role="button"><i class="fa fa-chevron-left"></i></a>
{% endif %}
{% if page_data.next_ordinal < flow_session.page_count %}
<a class="btn btn-default relate-nav-button"
href="{% url "relate-view_flow_page" course.identifier flow_session.id page_data.next_ordinal %}"
title='{% trans "Next page" context "Next page/item in a flow" %}'
role="button"><i class="fa fa-chevron-right"></i></a>
{% else %}
<a class="btn btn-default relate-nav-button disabled"
href="#"
title='{% trans "Next page" context "Next page/item in a flow" %}'
role="button"><i class="fa fa-chevron-right"></i></a>
{% endif %}
<button id="btn_bookmark"
class="btn btn-default relate-flow-page-bookmark-button
{% if page_data.bookmarked %}
relate-bookmarked
{% endif %}
"
title="{% trans "Boomark this page" %}">
<i id="label_bookmark_indicator" class="fa
{% if page_data.bookmarked %}
fa-star
{% else %}
fa-star-o
{% endif %}
" aria-hidden="true"></i>
</button>
</div>
<div class="relate-well">
<div>
{# }}} #}
{# {{{ prev/next buttons #}
{# {{{ send email button #}
{% if may_send_email_about_flow_page %}
<div class="navbar-right relate-flow-page-send-email"
style="padding-right: 0.4em;">
<a href="{% url 'relate-flow_page_interaction_email' course.identifier flow_session.id ordinal %}"
class="btn btn-default relate-nav-button btn-info"
title="{% trans 'Send an email about this page to course staff' %}"
target="_blank"
>
<i class="fa fa-envelope-o" aria-hidden="true"></i>
</a>
<div class="flow-nav d-flex gap-2 float-start mb-2">
{% if page_data.page_ordinal > 0 %}
<a class="btn btn-secondary relate-nav-button"
href="{% url "relate-view_flow_page" course.identifier flow_session.id page_data.previous_ordinal %}"
title='{% trans "Previous page" context "Previous page/item in a flow" %}'
role="button"><i class="bi bi-chevron-left"></i></a>
{% else %}
<a class="btn btn-secondary relate-nav-button disabled"
href="#"
title='{% trans "Previous page" context "Previous page/item in a flow" %}'
role="button"><i class="bi bi-chevron-left"></i></a>
{% endif %}
{% if page_data.next_ordinal < flow_session.page_count %}
<a class="btn btn-secondary relate-nav-button"
href="{% url "relate-view_flow_page" course.identifier flow_session.id page_data.next_ordinal %}"
title='{% trans "Next page" context "Next page/item in a flow" %}'
role="button"><i class="bi bi-chevron-right"></i></a>
{% else %}
<a class="btn btn-secondary relate-nav-button disabled"
href="#"
title='{% trans "Next page" context "Next page/item in a flow" %}'
role="button"><i class="bi bi-chevron-right"></i></a>
{% endif %}
<button id="btn_bookmark"
class="btn relate-flow-page-bookmark-button
{% if page_data.bookmarked %}
relate-bookmarked
{% endif %}
"
title="{% trans "Bookmark this page" %}">
<i id="label_bookmark_indicator" class="fa
{% if page_data.bookmarked %}
bi-star-fill
{% else %}
bi-star
{% endif %}
" aria-hidden="true"></i>
</button>
</div>
{% endif %}
{# }}} #}
{# {{{ menu #}
{# }}} #}
<div class="navbar-right relate-flow-page-menu"
style="padding-right: 0.4em;">
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="menu_dropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"
title='{% trans "Page Menu" %}'>
<i class="fa fa-bars"></i>
</button>
<ul class="dropdown-menu" aria-labelledby="menu_dropdown">
<li>
<a href='{% url "relate-view_start_flow" course.identifier flow_session.flow_id %}'
>{% trans "Return to flow start page" %}</a>
</li>
{% if page_expect_answer_and_gradable %}
{% if pperm.reopen_flow_session and not flow_session.in_progress and opportunity.id != None %}
<li>
<a href="{% url 'relate-view_reopen_session' course.identifier flow_session.id opportunity.id %}"
target="_blank">
{% trans "Reopen" %} <i class="fa fa-lock" aria-hidden="true"></i>
</a>
</li>
{% endif %}
{% if page_expect_answer_and_gradable and pperm.grant_exception and flow_session.participation.id != None %}
<li>
<a href="{% url 'relate-grant_exception_stage_3' course.identifier flow_session.participation.id flow_session.flow_id flow_session.id %}"
target="_blank">
{% trans "Grant exception" %} <i class="fa fa-lock" aria-hidden="true"></i>
</a>
</li>
{% endif %}
{% if pperm.view_gradebook %}
<li>
<a href="{% url 'relate-grade_flow_page' course.identifier flow_session.id ordinal %}"
target="_blank">
{% trans "View in grading interface" %} <i class="fa fa-lock" aria-hidden="true"></i>
</a>
</li>
{% endif %}
{% endif %}
</ul>
</div>
</div>
<div class="relate-flow-controls float-end d-flex gap-2 mb-2">
{# }}} #}
{# {{{ expiration mode #}
{# {{{ past submissions #}
{% if flow_session.in_progress and expiration_mode_choice_count > 1 and not viewing_prior_version %}
<div class="flow-session-expiration-panel d-flex text-nowrap align-items-baseline gap-1">
<span id="expiration_mode_change_progress">
</span>
<label class="form-label" for="id_expiration_mode">
{# Translators: the string is followed by "what will happen" at deadline. #}
{% trans "At deadline:" %}
</label>
<select class="form-select" id="id_expiration_mode"
name="expiration_mode">
{% for key, val in expiration_mode_choices %}
<option value="{{ key }}"
{% if key == expiration_mode %}
selected
{% endif %}
>{{ val }}</option>
{% endfor %}
</select>
</div>
{% endif %}
{% if prev_answer_visits|length > 1 %}
<div class="navbar-right relate-flow-page-past-submissions"
style="padding-right: 0.4em; margin-right:0;">
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="past-submission_dropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"
title='{% trans "Submission history for this page" %}'>
<i class="fa fa-history"></i>
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="past-submission_dropdown">
{% for pvisit in prev_answer_visits %}
<li>
{% if forloop.first %}
<a href="?">
{% else %}
<a href="?visit_id={{ pvisit.id }}">
{% endif %}
{# }}} #}
{# {{{ send email button #}
{% if may_send_email_about_flow_page %}
<div class="relate-flow-page-send-email">
<a href="{% url 'relate-flow_page_interaction_email' course.identifier flow_session.id page_ordinal %}"
class="btn btn-secondary relate-nav-button btn-info"
title="{% trans 'Send an email about this page to course staff' %}"
target="_blank"
>
<i class="bi bi-envelope" aria-hidden="true"></i>
</a>
</div>
{% endif %}
{# }}} #}
{# {{{ past submissions #}
{% if expects_answer %}
<div class="relate-flow-page-past-submissions">
<div class="dropdown" id="past-submission_dropdown">
<button
class="btn btn-outline-secondary dropdown-toggle"
type="button" id="past-submission_dropdown_button"
hx-get="{% url "relate-get_prev_answer_visits_dropdown_content" course.identifier flow_session.id page_ordinal prev_visit_id %}"
hx-target="#past-submission_dropdown_content"
data-bs-toggle="dropdown"
title='{% trans "Submission history for this page" %}'>
<i class="bi bi-clock-history"></i>
</button>
<ul
class="dropdown-menu dropdown-menu-end shadow"
aria-labelledby="past-submission_dropdown_button"
id="past-submission_dropdown_content">
<li style="list-style:none; position:relative; left:50%;">
<i class="bi bi-hourglass"></i>
</li>
</ul>
</div>
</div>
{% endif %}
{% if prev_visit_id == pvisit.id %}<b>{% endif %}
{{ pvisit.visit_time }}
{% if prev_visit_id == pvisit.id %}</b>{% endif %}
{% if forloop.first %}
{% trans "(current)" %}
{% endif %}
{% if pvisit.is_submitted_answer %}
{% trans "(submitted)" %}
{% endif %}
</a></li>
{% endfor %}
</ul>
</div>
</div>
{% endif %}
{# }}} #}
{# }}} #}
{# {{{ menu #}
{# {{{ 'finish' button #}
<div class="relate-flow-page-menu">
<div class="dropdown">
<button class="btn btn-outline-secondary dropdown-toggle" type="button" id="FlowPageMenuDropdown" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="true"
title='{% trans "Page Menu" %}'>
<i class="bi bi-list"></i>
</button>
<ul class="dropdown-menu dropdown-menu-end shadow" aria-labelledby="FlowPageMenuDropdown">
<li><h6 class="dropdown-header">{{ flow_desc.title }}</h6></li>
<li>
<a class="dropdown-item" href='{% url "relate-view_start_flow" course.identifier flow_session.flow_id %}'
>{% trans "Return to flow start page" %}</a>
</li>
{% if page_expect_answer_and_gradable %}
<li role="separator" class="divider"></li>
{% if pperm.reopen_flow_session and not flow_session.in_progress and opportunity.id != None %}
<li>
<a href="{% url 'relate-view_reopen_session' course.identifier flow_session.id opportunity.id %}"
target="_blank">
{% trans "Reopen" %} <i class="bi bi-unlock" aria-hidden="true"></i>
</a>
</li>
{% endif %}
{% if page_expect_answer_and_gradable and pperm.grant_exception and flow_session.participation.id != None %}
<li>
<a class="dropdown-item" href="{% url 'relate-grant_exception_stage_3' course.identifier flow_session.participation.id flow_session.flow_id flow_session.id %}"
target="_blank">
{% trans "Grant exception" %} <i class="bi bi-unlock" aria-hidden="true"></i>
</a>
</li>
{% endif %}
{% if pperm.view_gradebook %}
<li>
<a class="dropdown-item" href="{% url 'relate-grade_flow_page' course.identifier flow_session.id page_ordinal %}"
target="_blank">
{% trans "View in grading interface" %} <i class="bi bi-unlock" aria-hidden="true"></i>
</a>
</li>
{% endif %}
{% endif %}
{% if pperm.reopen_flow_session and flow_session.in_progress and expects_answer and not may_change_answer %}
<li role="separator" class="divider"></li>
<li>
<a class="dropdown-item" href="{% url 'relate-unsubmit_flow_page' course.identifier flow_session.id page_ordinal %}">
{% trans "Re-allow changes to page" %} <i class="bi bi-unlock" aria-hidden="true"></i>
</a>
</li>
{% endif %}
</ul>
</div>
</div>
<div class="navbar-right relate-flow-submit"
style="padding-right: 0.4em;">
<button type="submit" name="finish" class="btn btn-default relate-nav-button
{% if flow_session.in_progress %}
{% if not interaction_kind == flow_session_interaction_kind.noninteractive %}
btn-success
{% endif %}
{% endif %}"
title='
{% if interaction_kind == flow_session_interaction_kind.noninteractive %}
{% trans "Go to end" %}
{% elif flow_session.in_progress %}
{% if interaction_kind == flow_session_interaction_kind.ungraded %}
{% trans "Submit" %}
{% elif interaction_kind == flow_session_interaction_kind.permanent_grade %}
{% trans "Submit assignment" %}
{% else %}
{% trans "Finish" %}
{% endif %}
{% elif not flow_session.in_progress %}
{% if interaction_kind == flow_session_interaction_kind.ungraded or interaction_kind == flow_session_interaction_kind.permanent_grade %}
{% trans "Result" %}
{% else %}
{% trans "Finish" %}
{% endif %}
{% endif %}
'>
{% if interaction_kind == flow_session_interaction_kind.permanent_grade or interaction_kind == flow_session_interaction_kind.ungraded %}
{% if flow_session.in_progress %}
<i class="fa fa-check" aria-hidden="true"></i>
{% else %}
<i class="fa fa-bar-chart" aria-hidden="true"></i>
{% endif %}
{% else %}
<i class="fa fa-sign-out" aria-hidden="true"></i>
{% endif %}
</button>
</div>
{# }}} #}
{# }}} #}
{# {{{ 'finish' button #}
{# {{{ expiration mode #}
{% if flow_session.in_progress and expiration_mode_choice_count > 1 %}
<div class="flow-session-expiration-panel">
<span id="expiration_mode_change_progress">
</span>
<label for="id_expiration_mode">
{# Translators: the string is followed by "what will happen" at deadline. #}
{% trans "At deadline:" %}
</label>
<select class="select form-control" id="id_expiration_mode"
name="expiration_mode">
{% for key, val in expiration_mode_choices %}
<option value="{{ key }}"
{% if key == expiration_mode %}
selected
<div class="relate-flow-submit">
{% if not viewing_prior_version %}
<button type="submit" name="finish" class="btn btn-secondary relate-nav-button
{% if flow_session.in_progress %}
{% if not interaction_kind == flow_session_interaction_kind.noninteractive %}
btn-success
{% endif %}
>{{ val }}</option>
{% endfor %}
</select>
</div>
{% endif %}
{% endif %}"
title='
{% if interaction_kind == flow_session_interaction_kind.noninteractive %}
{% trans "Go to end" %}
{% elif flow_session.in_progress %}
{% if interaction_kind == flow_session_interaction_kind.ungraded %}
{% trans "Submit" %}
{% elif interaction_kind == flow_session_interaction_kind.permanent_grade %}
{% blocktrans with flow_title=flow_desc.title %}Submit {{ flow_title }}{% endblocktrans %}
{% else %}
{% trans "Finish" %}
{% endif %}
{% elif not flow_session.in_progress %}
{% if interaction_kind == flow_session_interaction_kind.ungraded or interaction_kind == flow_session_interaction_kind.permanent_grade %}
{% trans "Result" %}
{% else %}
{% trans "Finish" %}
{% endif %}
{% endif %}
'>
{% if interaction_kind == flow_session_interaction_kind.permanent_grade or interaction_kind == flow_session_interaction_kind.ungraded %}
{% if flow_session.in_progress %}
<i class="bi bi-check" aria-hidden="true"></i>
{% else %}
<i class="bi bi-bar-chart" aria-hidden="true"></i>
{% endif %}
{% else %}
<i class="bi bi-box-arrow-right" aria-hidden="true"></i>
{% endif %}
</button>
{% endif %}
</div>
{# }}} #}
{# }}} #}
{# {{{ toc #}
</div> {# .relate-flow-controls #}
<div class="relate-flow-page-toc">
{% for other_page_data in all_page_data %}
{% if other_page_data.ordinal == page_data.ordinal %}
<span class="relate-flow-page-toc-item btn btn-default btn-xs disabled
relate-current
{% if other_page_data.bookmarked %}
relate-bookmarked
{% endif %}
">{{ other_page_data.human_readable_ordinal }}</span>
{% else %}
<a href="{% url "relate-view_flow_page" course.identifier flow_session.id other_page_data.ordinal %}"
title="{{ other_page_data.title }}">
<span class="relate-flow-page-toc-item btn btn-default btn-xs
{% if page_nr < page_data.ordinal %}
relate-prior
{% else %}
relate-subsequent
{% endif %}
{% if other_page_data.bookmarked %}
relate-bookmarked
{% endif %}
{% if other_page_data.ordinal in flow_page_ordinals_with_answers %}
relate-answered
{# {{{ toc #}
<div class="relate-flow-page-toc d-flex gap-2 justify-content-center flex-wrap order-3 order-md-1 mx-auto">
{% for other_page_data in all_page_data %}
{% if other_page_data.page_ordinal == page_data.page_ordinal %}
<span class="relate-flow-page-toc-item btn btn-secondary btn-sm disabled
relate-current
{% if other_page_data.bookmarked %}
relate-bookmarked
{% endif %}
">{{ other_page_data.human_readable_ordinal }}</span>
{% else %}
<a href="{% url "relate-view_flow_page" course.identifier flow_session.id other_page_data.page_ordinal %}"
title="{{ other_page_data.title|safe }}">
<span class="relate-flow-page-toc-item btn btn-outline-secondary btn-sm
{% if page_nr < page_data.page_ordinal %}
relate-prior
{% else %}
relate-subsequent
{% endif %}
{% if other_page_data.bookmarked %}
relate-bookmarked
{% endif %}
{% if other_page_data.page_ordinal in flow_page_ordinals_with_answers %}
relate-answered
{% endif %}
">{{ other_page_data.human_readable_ordinal }}
</span></a>
{% endif %}
">{{ other_page_data.human_readable_ordinal }}
</span></a>
{% endif %}
{% endfor %}
{% if flow_session.page_count >= 4 %}
<span class="dropdown">
<span class="btn btn-default btn-xs dropdown-toggle relate-flow-page-toc-item " id="toc-dropdown" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="true">
<span class="caret"></span>
</span>
<ul class="dropdown-menu" aria-labelledby="toc-dropdown">
{% for other_page_data in all_page_data %}
<li>
<a href="{% url "relate-view_flow_page" course.identifier flow_session.id other_page_data.ordinal %}">
{{ other_page_data.human_readable_ordinal }}: {{ other_page_data.title }}
{% if other_page_data.bookmarked %}
<i class="fa fa-star" aria-hidden="true"></i>
{% endif %}
</a>
</li>
{% endfor %}
</ul>
</span>
{% endif %}
</div>
{% endfor %}
{# }}} #}
{% if flow_session.page_count >= 4 %}
<span class="dropdown">
<span class="btn btn-outline-secondary btn-sm dropdown-toggle relate-flow-page-toc-item " id="toc-dropdown" data-bs-toggle="dropdown">
</span>
<ul class="dropdown-menu dropdown-menu-end shadow" aria-labelledby="toc-dropdown">
{% for other_page_data in all_page_data %}
<li>
<a class="dropdown-item" href="{% url "relate-view_flow_page" course.identifier flow_session.id other_page_data.page_ordinal %}">
{{ other_page_data.human_readable_ordinal }}: {{ other_page_data.title|safe }}
{% if other_page_data.bookmarked %}
<i class="bi bi-star-fill" aria-hidden="true"></i>
{% endif %}
</a>
</li>
{% endfor %}
</ul>
</span>
{% endif %}
</div>
{# }}} #}
<div style="clear:both; height:0px"></div>
</div>
{# {{{ session time #}
......@@ -296,7 +318,7 @@
{% trans "minutes" %}
{% if time_factor != 1 %}
({% trans "Time factor:" %} {{ time_factor|floatformat:2 }}x)
({% trans "Time factor:" %} {{ time_factor|floatformat:2 }}x)
{% endif %}
</div>
{% endif %}
......@@ -309,14 +331,20 @@
{# {{{ points #}
{% if max_points %}
<div style="float:right" class="well">
{% blocktrans trimmed count counter=max_points %}
{{ max_points }} point
{% plural %}
{{ max_points }} points
{% endblocktrans %}
</div>
{% if not hide_point_count %}
{% if max_points %}
<div style="float:right" class="relate-well">
{% blocktrans trimmed count counter=max_points %}
{{ max_points }} point
{% plural %}
{{ max_points }} points
{% endblocktrans %}
</div>
{% elif is_optional_page %}
<div style="float:right" class="relate-well">
{% trans "Optional question" %}
</div>
{% endif %}
{% endif %}
{# }}} #}
......@@ -326,7 +354,7 @@
{# {{{ form #}
{% if form_html %}
<div class="well relate-interaction-container">
<div class="relate-well relate-interaction-container">
{{ form_html|safe }}
{% if may_change_graded_answer and will_receive_feedback %}
......@@ -355,9 +383,9 @@
alert-info
{% endif %}
">
<p>{{ feedback.feedback|safe }}</p>
<p>{% trans feedback.feedback|safe %}</p>
{% if feedback.bulk_feedback %}
<p>{{ feedback.bulk_feedback|safe }}</p>
<p>{% trans feedback.bulk_feedback|safe %}</p>
{% endif %}
{% if show_answer and correct_answer %}
<p>{{ correct_answer|safe }}</p>
......@@ -365,7 +393,7 @@
</div>
{% elif show_answer and correct_answer %}
{# show only correct answer, without indication of correctness #}
<div class="well">
<div class="relate-well">
<p>{{ correct_answer|safe }}</p>
</div>
{% endif %}
......@@ -380,22 +408,6 @@
{
var input_changed = false;
// {{{ listen for codemirror changes
function on_cm_change(cm, change_obj)
{
input_changed = true;
}
$("div.CodeMirror").each(
function ()
{
var cm = this.CodeMirror;
cm.on("change", on_cm_change);
});
// }}}
// {{{ listen for other input changes
function on_input_change(evt)
......@@ -406,6 +418,7 @@
$(":checkbox").on("change", on_input_change);
$(":radio").on("change", on_input_change);
$(":text").on("change", on_input_change);
$(":file").on("change", on_input_change);
$("textarea").on("change", on_input_change);
// }}}
......@@ -413,18 +426,24 @@
$(window).on('beforeunload',
function()
{
if (input_changed)
if (input_changed
|| ((typeof rlCodemirror !== 'undefined') && rlCodemirror.anyEditorChanged())
|| ((typeof rlProsemirror !== 'undefined') && rlProsemirror.anyEditorChanged())
)
return "{% trans 'You have unsaved changes on this page.' %}";
});
function before_submit(evt)
{
input_changed = false;
if (rlCodemirror)
rlCodemirror.resetAnyEditorChanged();
if (rlProsemirror)
rlProsemirror.resetAnyEditorChanged();
// We can't simply set "disabled" on the submitting button here.
// Otherwise the browser will simply remove that button from the POST
// data.
$(".relate-save-button").each(
function()
{
......@@ -448,22 +467,6 @@
<script type="text/javascript">
// using jQuery
function get_cookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function expiration_mode_changed()
{
$("#expiration_mode_change_progress")
......@@ -479,7 +482,7 @@
expiration_mode: $("#id_expiration_mode").val()
},
beforeSend: function(xhr, settings) {
var csrftoken = get_cookie('csrftoken');
var csrftoken = rlUtils.getCookie('relate_csrftoken');
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
})
......@@ -516,31 +519,31 @@
evt.preventDefault();
var ind = $("#label_bookmark_indicator");
var prev_bookmarked = ind.hasClass("fa-star");
var prev_bookmarked = ind.hasClass("bi-star-fill");
var new_bookmarked = !prev_bookmarked;
if (new_bookmarked)
{
ind.removeClass("fa-star-o");
ind.addClass("fa-star");
ind.removeClass("bi-star");
ind.addClass("bi-star-fill");
btn_bookmark.addClass("relate-bookmarked");
}
else
{
ind.removeClass("fa-star");
ind.addClass("fa-star-o");
ind.removeClass("bi-star-fill");
ind.addClass("bi-star");
btn_bookmark.removeClass("relate-bookmarked");
}
var jqxhr = $.ajax(
"{% url "relate-update_page_bookmark_state" course.identifier flow_session.id page_data.ordinal %}",
"{% url "relate-update_page_bookmark_state" course.identifier flow_session.id page_data.page_ordinal %}",
{
type: "POST",
data: {
bookmark_state: new_bookmarked ? "1": "0"
},
beforeSend: function(xhr, settings) {
var csrftoken = get_cookie('csrftoken');
var csrftoken = rlUtils.getCookie('relate_csrftoken');
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
})
......@@ -554,36 +557,6 @@
{# }}} #}
{# {{{ codemirror resizing, save #}
<script type="text/javascript">
$("div.CodeMirror")
.resizable({
resize: function (event, ui)
{
$("div.CodeMirror").each(
function ()
{
var cm = this.CodeMirror;
cm.refresh();
});
}
})
.each(
function ()
{
function submit_page_for_feedback()
{
$(".relate-submit-button").click();
}
var cm = this.CodeMirror;
cm.save = submit_page_for_feedback;
});
</script>
{# }}} #}
{% endblock %}
{# vim: set foldmethod=marker: #}
{% load i18n %}
{% if flow_session.in_progress %}
<span class="label label-warning">{% trans "unfinished" %}</span>
{% if not flow_session %}
<span class="badge bg-danger">{% trans "not started" %}</span>
{% elif flow_session.in_progress %}
<span class="badge bg-warning">{% trans "unfinished" %}</span>
{% else %}
<span class="label label-success">{% trans "finished" %}</span>
<span class="badge bg-success">{% trans "finished" %}</span>
{% endif %}
......@@ -3,19 +3,17 @@
{% block title %}
{{flow_desc.title}} - {% trans "RELATE" %}
{{flow_desc.title}} - {{ relate_site_name }}
{% endblock %}
{% block content %}
{% if flow_desc.description %}
{{flow_desc.description_html|safe}}
{% endif %}
{{ flow_description_html|safe }}
<form method="POST">
{% csrf_token %}
{% if past_sessions_and_properties %}
<div class="well">
<div class="relate-well">
<h3 class="start-well-title">{% trans "Past sessions" %}</h3>
<table class="past-flow-session-table">
......@@ -51,7 +49,7 @@
<td>
{% if session_properties.grade_shown %}
{% if flow_session.points_percentage != None %}
{% blocktrans trimmed with points=flow_session.points|floatformat max_points=flow_session.max_points|floatformat percentage=flow_session.points_percentage|floatformat %}
{% blocktrans trimmed with points=flow_session.points|floatformat:"-2" max_points=flow_session.max_points|floatformat:"-2" percentage=flow_session.points_percentage|floatformat:"-2" %}
<b>{{ points }}</b>
out of
{{ max_points }}
......@@ -68,7 +66,7 @@
</td>
<td>
{% if session_properties.may_view %}
<a href="{% url "relate-view_resume_flow" course.identifier flow_session.id %}" class="btn btn-primary btn-xs">
<a href="{% url "relate-view_resume_flow" course.identifier flow_session.id %}" class="btn btn-primary btn-sm">
{% if session_properties.may_modify %}
{% trans "Resume" %} &raquo;
{% else %}
......@@ -77,7 +75,7 @@
</a>
{% if not flow_session.in_progress %}
<a href="{% url "relate-finish_flow_session_view" course.identifier flow_session.id %}" class="btn btn-primary btn-xs">
<a href="{% url "relate-finish_flow_session_view" course.identifier flow_session.id %}" class="btn btn-primary btn-sm">
{% trans "Results" %}
</a>
{% endif %}
......@@ -109,7 +107,7 @@
</li>
{% endif %}
<li>
{% blocktrans trimmed with credit_percent=new_session_grading_rule.credit_percent|floatformat%}
{% blocktrans trimmed with credit_percent=new_session_grading_rule.credit_percent|floatformat:"-2" %}
You will receive <b>{{ credit_percent }}% credit</b>
for your work.
{% endblocktrans %}
......@@ -119,7 +117,7 @@
{% blocktrans trimmed %}
This is not your first session. If you start another one,
for your overall grade we will '<b>{{ grade_aggregation_strategy_descr }}</b>'
among all your sessions.
among all your graded sessions.
{% endblocktrans %}
</li>
{% endif%}
......@@ -135,12 +133,12 @@
</a>
<button id="start-button" type="submit" name="start" class="btn btn-danger"
style="display:none"
data-content='<p>{% trans "I understand that starting a new session could lower my overall grade." %}</p>
<button id="cancel-button" type="reset" name="cancel" class="btn btn-primary btn-sm" style="float: right;">
{% trans "Cancel" %}</button>'
data-html="true"
data-container="body"
data-placement="right"
data-bs-content='<p>{% trans "I understand that starting a new session could lower my overall grade." %}</p>
<a href="#" id="cancel-button" name="cancel" class="btn btn-primary btn-sm">
{% trans "Cancel" %}</a>'
data-bs-html="true"
data-bs-container="body"
data-bs-placement="right"
>
{# Translators: student should confirm to start another session. #}
{% trans "I am sure" %} &raquo;
......@@ -195,9 +193,9 @@
{% else %}
<div class="alert alert-info">
<p>
<i class="fa fa-exclamation-triangle"></i>
<i class="bi bi-exclamation-triangle"></i>
{% blocktrans trimmed %}
You do not have any existing sessions and are not allowed to start
You do not have any existing/viewable sessions and are not allowed to start
a new one.
{% endblocktrans %}
</p>
......@@ -212,7 +210,7 @@
{% blocktrans trimmed %}
You're not currently signed in. Access to the resource is restricted,
and since the site has no way of knowing who you are, it may have denied
you accesss.
you access.
Once you're signed in, navigate back to your course from the
<a href="{{ relate-home }}"> home page </a> and retry your last
action.
......
{% extends "course/course-base.html" %}
{% load i18n %}
{% load static %}
{% load crispy_forms_tags %}
{% block title %}
{{ form_description }} - {{ relate_site_name }}
{% endblock %}
{% block content %}
{% if form_description %}
<h1>{{ form_description }}</h1>
......@@ -10,14 +15,14 @@
{{ form_text|safe }}
{% if form %}
<div class="well">
<div class="relate-well">
{% crispy form %}
</div>
{% endif %}
{% if forms %}
{% for sub_form in forms %}
<div class="well">
<div class="relate-well">
{% crispy sub_form %}
</div>
{% endfor %}
......
{% load i18n %}
<table class='table'>
<tr>
<th>{% trans "Git Source URL" %}</th>
<td><tt>{{ course.git_source }}</tt></td>
</tr>
<tr>
<th>{% trans "Public active git SHA" %}</th>
<td>{{ course.active_git_commit_sha }}
({{course.active_git_commit_sha|commit_message_as_html:repo|safe }})</td>
</tr>
<tr>
<th>{% trans "Current git HEAD" %}</th>
<td>{{ current_git_head }}
({{ current_git_head|commit_message_as_html:repo|safe }})</td>
</tr>
<tr><th>{% trans "Current preview git SHA" %}</th>
{% if is_previewing %}
<td>{{ participation.preview_git_commit_sha}}
({{ participation.preview_git_commit_sha|commit_message_as_html:repo|safe }})</td>
{% else %}
<td>{% trans "None" %}</td>
{% endif %}
</tr>
<tr><th>{% trans "Direct git endpoint" %}</th>
<td><tt>{{ git_url }}</tt> (<a href="{{token_url}}">{% trans "Manage access tokens" %}</a>)
</td>
</tr>
</table>
{% extends "course/course-base.html" %}
{% extends "course/course-base-with-markup.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block title %}
{{ page_data.group_id }}/{{ page_data.page_id }} - {{ flow_identifier}} - {% trans "Grading" %} - {% trans "RELATE" %}
{{ page_data.group_id }}/{{ page_data.page_id }} - {{ flow_identifier}} - {% trans "Grading" %} - {{ relate_site_name }}
{% endblock %}
{% block root_container %}
<div class="grading-page-student-work">
<div class="row">
<div class="row">
<div class="grading-page-student-work container pt-2">
{# {{{ student view #}
{# {{{ past submissions #}
<div style="float: right; padding-top:1.5em; margin-right:0 !important;" class="navbar-right">
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="past-submission_dropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
{% trans "Past submissions/grades" %}
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="past-submission_dropdown">
{% for pgrade in prev_grades %}
<li>
{% if forloop.first %}
<a href="?">
{% else %}
<a href="?grade_id={{ pgrade.id }}">
{% endif %}
{% if prev_grade_id == pgrade.id %}<b>{% endif %}
{% trans "Submission:" %} {{ pgrade.visit.visit_time }}
&middot; {% trans "Grade:" %}
{{ pgrade.grade_time }}
{% if prev_grade_id == pgrade.id %}</b>{% endif %}
{% if forloop.first %}
{% trans "(current)" %}
{% endif %}
{% if pgrade.value == None %}
[{% trans "no grade" %}]
{% else %}
[{{ pgrade.value}} {% trans "points" %}]
{% endif %}
</a></li>
{% endfor %}
</ul>
<div class="card mb-3" markdown="block">
<div class="card-header">
<h5 class="card-title dropdown-toggle">
<a class="text-decoration-none link-secondary"
data-bs-toggle="collapse" href="#grading-prompt" aria-expanded="false" aria-controls="grading-prompt">
{% trans "Prompt" %}
</a>
</h5>
</div>
<div id="grading-prompt" class="collapse">
<div class="card-body">
{{ body|safe }}
</div>
</div>
</div>
{# }}} #}
{{ body|safe }}
{% if form_html %}
<div class="well">
<div class="relate-well relate-interaction-container">
{{ form_html|safe }}
</div>
{% endif %}
......@@ -78,31 +54,34 @@
{# }}} #}
</div>
</div>
<div class="grading-page-grade-entry">
<div class="row">
<div class="grading-page-grade-entry container pt-2">
<h1> {% trans "Grading" %}: <tt>{{ flow_identifier}} - {{ page_data.group_id }}/{{ page_data.page_id }}</tt> </h1>
{% include "base-page-top.html" %}
{# {{{ header table #}
<table class="table table-condensed">
<thead>
<th>{% trans "Property" %}</th><th>{% trans "Value" %}</th>
</thead>
<tbody>
{% if grading_opportunity != None %}
<tr>
<td>{% trans "Flow session" %}</td>
<td>
<tt><a href="{% url "relate-view_single_grade" course.identifier flow_session.participation.id grading_opportunity.id %}"><i class="fa fa-level-up"></i> {{ flow_identifier }}</a></tt>
<tt><a href="{% url "relate-view_single_grade" course.identifier flow_session.participation.id grading_opportunity.id %}"><i class="bi bi-arrow-90deg-up"></i> {{ flow_identifier }}</a></tt>
<span class="sensitive">
{# Translators: the grade information "for" a participant with fullname + (username) #}
{% blocktrans trimmed with full_name=flow_session.participation.user.get_full_name username=flow_session.participation.user.username %}
for
{{ full_name }}
({{ username }})
{% endblocktrans %}
{% if not pperm.view_participant_masked_profile %}
{# Translators: the grade information "for" a participant #}
{% blocktrans trimmed with full_name=flow_session.participation.user.get_full_name username=flow_session.participation.user.username %}
for
{{ full_name }}
({{ username }})
{% endblocktrans %}
{% else %}
{# Translators: the grade information "for" a participant #}
{% blocktrans trimmed with masked_user_profile=flow_session.participation.user.get_masked_profile %}
for
{{ masked_user_profile }}
{% endblocktrans %}
{% endif %}
</span>
</td>
</tr>
......@@ -113,7 +92,7 @@
{% if max_points != None %}
<span class="sensitive">
{% if points_awarded != None %}
{{ points_awarded|floatformat:1 }}
{{ points_awarded|floatformat:"-2" }}
{% else %}
{% trans "(unknown)" %}
{% endif %}
......@@ -129,6 +108,27 @@
{% else %}
{% trans "(n/a)" %}
{% endif %}
{% if expects_answer %}
<div class="dropdown" id="past-submission-and-grades_dropdown">
<button
class="btn btn-sm btn-outline-secondary dropdown-toggle"
type="button" id="past-submission-and-grades_dropdown_button"
hx-get='{% url "relate-get_prev_grades_dropdown_content" course.identifier flow_session.id page_ordinal prev_grade_id %}'
hx-target="#past-submission-and-grades_dropdown_content"
data-bs-toggle="dropdown">
{% trans "Past submissions/grades" %}
<span class="caret"></span>
</button>
<ul class="dropdown-menu dropdown-menu shadow"
aria-labelledby="past-submission-and-grades_dropdown_button"
id="past-submission-and-grades_dropdown_content">
<li style="list-style:none; position:relative; left:50%;">
<i class="bi bi-hourglass"></i>
</li>
</ul>
</div>
{% endif %}
</td>
</tr>
<tr>
......@@ -154,16 +154,16 @@
<tr>
<td>
{% if prev_flow_session_id != None %}
<a href="{% url "relate-grade_flow_page" course.identifier prev_flow_session_id page_data.ordinal %}"
accesskey="p" class="btn btn-default" title="Alt/Cmd(+Shift+)p"><i class="fa fa-chevron-left"></i></a>
<a href="{% url "relate-grade_flow_page" course.identifier prev_flow_session_id page_data.page_ordinal %}"
accesskey="p" class="btn btn-secondary" title="Alt/Cmd(+Shift+)p"><i class="bi bi-chevron-left"></i></a>
{% else %}
<a href="#" class="btn btn-default disabled"><i class="fa fa-chevron-left"></i></a>
<a href="#" class="btn btn-secondary disabled"><i class="bi bi-chevron-left"></i></a>
{% endif %}
{% if next_flow_session_id %}
<a href="{% url "relate-grade_flow_page" course.identifier next_flow_session_id page_data.ordinal %}"
accesskey="n" class="btn btn-default" title="Alt/Cmd+(Shift+)n"><i class="fa fa-chevron-right"></i></a>
<a href="{% url "relate-grade_flow_page" course.identifier next_flow_session_id page_data.page_ordinal %}"
accesskey="n" class="btn btn-secondary" title="Alt/Cmd+(Shift+)n"><i class="bi bi-chevron-right"></i></a>
{% else %}
<a href="#" class="btn btn-default disabled"><i class="fa fa-chevron-right"></i></a>
<a href="#" class="btn btn-secondary disabled"><i class="bi bi-chevron-right"></i></a>
{% endif %}
{% trans "Session" %}
</td>
......@@ -176,24 +176,24 @@
</tr>
<tr>
<td>
{% if page_data.ordinal > 0 %}
{% if page_data.page_ordinal > 0 %}
<a href="{% url "relate-grade_flow_page" course.identifier flow_session.id page_data.previous_ordinal %}"
class="btn btn-default"><i class="fa fa-chevron-left"></i></a>
class="btn btn-secondary"><i class="bi bi-chevron-left"></i></a>
{% else %}
<a href="#" class="btn btn-default disabled"><i class="fa fa-chevron-left"></i></a>
<a href="#" class="btn btn-secondary disabled"><i class="bi bi-chevron-left"></i></a>
{% endif %}
{% if page_data.next_ordinal < flow_session.page_count %}
<a href="{% url "relate-grade_flow_page" course.identifier flow_session.id page_data.next_ordinal %}"
class="btn btn-default"><i class="fa fa-chevron-right"></i></a>
class="btn btn-secondary"><i class="bi bi-chevron-right"></i></a>
{% else %}
<a href="#" class="btn btn-default disabled"><i class="fa fa-chevron-right"></i></a>
<a href="#" class="btn btn-secondary disabled"><i class="bi bi-chevron-right"></i></a>
{% endif %}
{% trans "Page number" %}
</td>
<td>
{{ ordinal }}
{{ page_ordinal }}
&middot;
<a href="{% url "relate-view_flow_page" course.identifier flow_session.id ordinal %}">{% trans "View in flow" %}</a>
<a href="{% url "relate-view_flow_page" course.identifier flow_session.id page_ordinal %}">{% trans "View in flow" %}</a>
</td>
</tr>
</table>
......@@ -210,9 +210,9 @@
{# {{{ correct answer #}
{% if correct_answer %}
<div class="panel panel-default">
<div class="panel-heading">{% trans "Correct Answer" %}</div>
<div class="panel-body">
<div class="card mt-3">
<div class="card-header">{% trans "Correct Answer" %}</div>
<div class="card-body">
<p>{{ correct_answer|safe }}</p>
</div>
</div>
......@@ -227,142 +227,198 @@
<script>
// http://stackoverflow.com/a/30558011
var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
// Match everything outside of normal chars and " (quote character)
NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g;
function encode_entities(value)
{
return value.
replace(/&/g, '&amp;').
replace(SURROGATE_PAIR_REGEXP, function(value) {
var hi = value.charCodeAt(0);
var low = value.charCodeAt(1);
return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
}).
replace(NON_ALPHANUMERIC_REGEXP, function(value) {
return '&#' + value.charCodeAt(0) + ';';
}).
replace(/</g, '&lt;').
replace(/>/g, '&gt;');
}
function truncate_text(s, length)
{
if (s.length > length)
return s.slice(0, length) + "...";
else
return s;
}
function set_grade_percent(p)
{
$("#id_grade_percent").val(p);
function getFeedbackCodemirror() {
let editorDom = document.querySelector('#div_id_feedback_text .cm-editor');
if (!editorDom)
return null;
return rlCodemirror.EditorView.findFromDOM(editorDom);
}
function set_grade_points(p)
{
$("#id_grade_points").val(p);
function setFeedback(p) {
const view = getFeedbackCodemirror();
const transaction = view.state.update({
changes: {
from: 0,
to: view.state.doc.length,
insert: p,
},
});
view.dispatch(transaction);
}
function set_feedback(p)
{
$("#id_feedback_text").val(p);
}
function get_feedback_items()
{
var items = localStorage["relate_grade_feedback_items"];
function getFeedbackItems() {
const items = localStorage["relate_grade_feedback_items"];
if (items)
return JSON.parse(items);
else
return [];
}
function add_feedback(idx)
{
var items = get_feedback_items();
function addFeedback(idx) {
const items = getFeedbackItems();
const view = getFeedbackCodemirror();
const currentValue = view.state.doc.toString();
var val = $("#id_feedback_text").val();
if (val)
let val = "";
if (currentValue)
val += "\n";
val += items[idx];
$("#id_feedback_text").val(val);
const transaction = view.state.update({
changes: {
from: view.state.doc.length,
to: view.state.doc.length,
insert: val,
},
});
view.dispatch(transaction);
}
function add_feedback_item(p)
{
var item = prompt("{%trans "Enter new feedback item:" %}");
function copyRubric() {
setFeedback(document.querySelector("#id_rubric_text").value);
}
function addFeedbackItem(p) {
const item = prompt("{%trans "Enter new feedback item:" %}");
if (!item)
return;
var items = get_feedback_items();
const items = getFeedbackItems();
items.push(item);
localStorage["relate_grade_feedback_items"] = JSON.stringify(items);
update_feedback_items();
updateFeedbackItems();
}
function remove_feedback_item(evt)
{
function removeFeedbackItem(evt) {
evt.stopPropagation();
var id = evt.target.parentNode.id.substr("remove_fb_".length);
var index = parseInt(id);
const id = evt.target.parentNode.id.substr("remove_fb_".length);
const index = parseInt(id);
var items = get_feedback_items();
const items = getFeedbackItems();
items.splice(index, 1);
localStorage["relate_grade_feedback_items"] = JSON.stringify(items);
update_feedback_items();
updateFeedbackItems();
}
function update_feedback_items()
{
var buttons = "";
function updateFeedbackItems() {
let buttons = "";
var items = get_feedback_items();
const items = getFeedbackItems();
buttons += "<p>";
buttons += "<div class='lh-lg mt-1'>";
for (var i = 0; i < items.length; ++i)
{
var fb = items[i];
buttons += ("<button class='btn btn-xs btn-default' type='button' "
+ "onclick='add_feedback(" + i + ")'>"
+ truncate_text(encode_entities(fb), 25)
buttons += ("<button class='btn btn-sm btn-outline-secondary' type='button' "
+ "onclick='addFeedback(" + i + ")'>"
+ rlUtils.truncateText(rlUtils.encodeEntities(fb), 25)
+ "</button>"
+ " <a class='remove_fb_button' id='remove_fb_"+i+"' href='#'>"
+ "<i class='fa fa-times-circle'></i>"
+ " <a class='remove_fb_button link-secondary' id='remove_fb_"+i+"' href='#'>"
+ "<i class='bi bi-x-circle'></i>"
+ "</a> "
);
}
buttons += "</p>";
buttons += "</div>";
buttons += "<p>";
buttons += ("<button class='btn btn-xs btn-default' type='button' "
+ "onclick='add_feedback_item()'><i class='fa fa-plus'></i> {% trans "Add phrase" %}</button>");
buttons += ("<button class='btn btn-xs btn-default' type='button' "
+ "onclick='set_feedback(\"\")'>{% trans "Clear" %}</button>");
buttons += "</p>";
buttons += "<div class='mt-1'>";
buttons += ("<button class='btn btn-sm btn-outline-secondary me-1' type='button' "
+ "onclick='addFeedbackItem()'><i class='bi bi-plus'></i> {% trans "Add phrase" %}</button>");
buttons += ("<button class='btn btn-sm btn-outline-secondary me-1' type='button' "
+ "onclick='copyRubric()'><i class='bi bi-clipboard-check'></i> {% trans "Copy rubric" %}</button>");
buttons += ("<button class='btn btn-sm btn-outline-danger me-1' type='button' "
+ "onclick='setFeedback(\"\")'>{% trans "Clear" %}</button>");
buttons += "</div>";
$("#canned_feedback_items").html(buttons);
$(".remove_fb_button").click(remove_feedback_item);
$(".remove_fb_button").click(removeFeedbackItem);
}
function add_grade_ui()
{
$(".grading-page-grade-entry #div_id_feedback_text .controls textarea").each(
function processFeedbackChange(feedbackText) {
try {
let maxPoints = null;
let points = null;
rlUtils.parsePointsSpecs(feedbackText).forEach(
pspec => {
if (pspec.points !== null) {
if (points === null)
points = 0;
points += pspec.points;
}
else {
throw new Error("Not applying points total when a pts spec "
+ "is missing a point value.");
}
if (pspec.maxPoints !== null)
{
if (maxPoints === null)
maxPoints = 0;
maxPoints += pspec.maxPoints;
}
})
if (points !== null)
{
if (maxPoints === null)
{
document.getElementById("id_grade_points").value = points;
document.getElementById("id_grade_percent").value = "";
}
else
{
document.getElementById("id_grade_points").value = "";
document.getElementById("id_grade_percent").value = 100*points/maxPoints;
}
}
}
catch (err)
{
bsUtils.showToast(err);
}
}
function listenForFocusHotkey(e) {
if (e.key === "F" && e.ctrlKey && e.shiftKey && !e.altKey && !e.metaKey
&& !e.isComposing) {
getFeedbackCodemirror().focus();
e.stopPropagation();
e.preventDefault();
}
}
function addGradeUI() {
$(".grading-page-grade-entry #id_feedback_text_helptext").each(
function()
{
$(this).after("<div id='canned_feedback_items'></div>");
});
update_feedback_items();
updateFeedbackItems();
let fbcm = getFeedbackCodemirror();
if (fbcm)
{
rlCodemirror.setListener(
getFeedbackCodemirror(),
(viewUpdate) => {
if (viewUpdate.docChanged) {
processFeedbackChange(viewUpdate.view.state.doc.toString())
}
})
}
document.addEventListener("keydown", listenForFocusHotkey);
}
$(document).ready(add_grade_ui);
$(document).ready(addGradeUI);
{% if page_data.next_ordinal < flow_session.page_count %}
var next_page_url = "{% url "relate-grade_flow_page" course.identifier flow_session.id page_data.next_ordinal %}";
......@@ -371,43 +427,51 @@
{% endif %}
{% if next_flow_session_id %}
var next_session_url = "{% url "relate-grade_flow_page" course.identifier next_flow_session_id page_data.ordinal %}";
var next_session_url = "{% url "relate-grade_flow_page" course.identifier next_flow_session_id page_data.page_ordinal %}";
{% else %}
var next_session_url = null;
{% endif %}
function save_and_next_page()
function saveAndNextPage()
{
window.open(next_page_url, "_blank");
$("#submit-id-submit").click();
}
function save_and_next_session()
function saveAndNextSession()
{
window.open(next_session_url, "_blank");
$("#submit-id-submit").click();
}
function add_submit_next()
function addSubmitNext()
{
if (next_page_url)
$(".grading-page-grade-entry .form-group:last .controls:last").append(
" <button class='btn btn-primary' id='save_next_page' type='button'>"
$(".grading-page-grade-entry .row:last div:last").append(
" <button class='btn btn-outline-primary' id='save_next_page' type='button'>"
+ "{% trans "Submit and next page" %} &raquo;"
+ "</button>");
if (next_session_url)
$(".grading-page-grade-entry .form-group:last .controls:last").append(
" <button class='btn btn-primary' id='save_next_session' type='button'>"
+ "{% trans "Submit and next session" %} &raquo;"
$(".grading-page-grade-entry .row:last div:last").append(
" <button class='btn btn-outline-primary' id='save_next_session' type='button'>"
+ "{% trans "Submit and next session (Alt+S)" %} &raquo;"
+ "</button>");
$("#save_next_page").click(save_and_next_page);
$("#save_next_session").click(save_and_next_session);
$("#save_next_page").click(saveAndNextPage);
$("#save_next_session").click(saveAndNextSession);
{# http://stackoverflow.com/a/9549716/3437454 #}
$(".relate-grading-form").prepend($(".row:last").clone(true, true));
$(".relate-grading-form").prepend($(".form-group:last"));
// Set only on one of the two copies, to avoid Firefox noticing
// an ambiguity.
let saveNext =document.getElementById('save_next_session');
if (saveNext) {
saveNext.accessKey = 's';
}
}
$(document).ready(add_submit_next);
$(document).ready(addSubmitNext);
</script>
{# }}} #}
......
......@@ -2,7 +2,7 @@
{% if log_lines %}
<div class="alert alert-warning">
<i class="fa fa-warning"></i>
<i class="bi bi-exclamation-triangle"></i>
<ul>
{% for line in log_lines %}
<li>{{ line }}</li>
......@@ -11,7 +11,7 @@
</div>
{% endif %}
{% if show_grade_changes %}
<div class="well">
<div class="relate-well">
<h2 class="start-well-title">{% trans "Preview" %}</h2>
<table class="table">
<thead>
......
{% load i18n %}
{% blocktrans with username=participation.user.get_email_appellation flow_id=flow_session.flow_id flow_id=flow_session.flow_id course_identifier=course.identifier feedback_text=feedback_text|safe %}Hi there,
{% blocktrans with flow_id=flow_session.flow_id flow_id=flow_session.flow_id course_identifier=course.identifier feedback_text=feedback_text|safe %}Hi there,
I am sending you the internal grading notes regarding {{username}}'s work on the page with title '{{ page_title }}' in '{{ flow_id }}' of '{{ course_identifier }}'. The full text of the notes follows.
-------------------------------------------------------------------
{{ notes_text }}
......
{% load i18n %}{% blocktrans trimmed with username=participation.user.get_email_appellation %}Dear {{username}},{% endblocktrans %}
{% load i18n %}{% if use_masked_profile %}{% trans "Dear user" %},{% else %}{% blocktrans trimmed with username=participation.user.get_email_appellation %}Dear {{username}},{% endblocktrans %}{% endif %}
{% blocktrans with flow_id=flow_session.flow_id flow_id=flow_session.flow_id course_identifier=course.identifier feedback_text=feedback_text|safe %}
You have a new notification regarding your work on the page with title '{{ page_title }}' in '{{ flow_id }}' of '{{ course_identifier }}'. The full text of the feedback follows.
-------------------------------------------------------------------
......
{% extends "course/course-base.html" %}
{% extends "course/course-datatables.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% load static %}
{% block title %}
{% trans "Grade book" %}: {{ opportunity.name }} - {% trans "RELATE" %}
{% trans "Grade book" %}: {{ opportunity.name }} - {{ relate_site_name }}
{% endblock %}
{% block header_extra %}
{% include "datatables-header.html" %}
{% endblock %}
{% block content %}
<h1>{% trans "Grade book" %}: {{ opportunity.name }} </h1>
......@@ -50,27 +45,27 @@
<tr>
<td>{% trans "Operations" %}</td>
<td>
<a class="btn btn-default" role="button"
<a class="btn btn-secondary" role="button"
href="{% url "relate-flow_analytics" course.identifier opportunity.flow_id %}">{% trans "View analytics" %}</a>
{% if pperm.view_grader_stats %}
<a class="btn btn-default" role="button"
<a class="btn btn-secondary" role="button"
href="{% url "relate-show_grader_statistics" course.identifier opportunity.flow_id %}">{% trans "View grader statistics" %}</a>
{% endif %}
{% if not view_page_grades %}
<a class="btn btn-default" role="button"
<a class="btn btn-secondary" role="button"
href="{% url "relate-view_grades_by_opportunity" course.identifier opportunity.id %}?view_page_grades=1">
{% trans "View page grades" %}</a>
{% else %}
<a class="btn btn-default" role="button"
<a class="btn btn-secondary" role="button"
href="{% url "relate-view_grades_by_opportunity" course.identifier opportunity.id %}">
{% trans "Hide page grades" %}</a>
{% endif %}
{% if pperm.batch_download_submission %}
<a class="btn btn-default" href="{% url "relate-download_all_submissions" course.identifier opportunity.flow_id %}"
<a class="btn btn-secondary" href="{% url "relate-download_all_submissions" course.identifier opportunity.flow_id %}"
role="button">{% trans "Download submissions" %}</a>
{% endif %}
{% if pperm.edit_grading_opportunity %}
<a class="btn btn-default" href="{% url "relate-edit_grading_opportunity" course.identifier opportunity.id %}"
<a class="btn btn-outline-secondary" href="{% url "relate-edit_grading_opportunity" course.identifier opportunity.id %}"
role="button">{% trans "Edit" %}</a>
{% endif %}
</td>
......@@ -79,7 +74,7 @@
</table>
{% if batch_session_ops_form %}
<div class="well" style="margin-top: 20px">
<div class="relate-well" style="margin-top: 20px">
<h3 class="start-well-title">{% trans "Modify many sessions at once" %}</h3>
{% crispy batch_session_ops_form %}
......@@ -114,93 +109,144 @@
<table class="table table-striped gradebook-by-opportunity">
<thead>
<th class="datacol">{% trans "User ID" %}</th>
<th class="datacol">{% trans "Name" context "real name of a user" %}</th>
{% if view_page_grades %}
{% for i in page_numbers %}
<th class="datacol">{{ i }}</th>
{% endfor %}
{% if not pperm.view_participant_masked_profile %}
<th class="datacol">{% trans "User ID" %}</th>
<th class="datacol">{% trans "Name" context "real name of a user" %}</th>
{% else %}
<th class="datacol">{% trans "User" %}</th>
{% endif %}
{% if opportunity.flow_id %}
{% if view_page_grades %}
{% for i in page_numbers %}
<th class="datacol">{{ i }}</th>
{% endfor %}
{% endif %}
<th class="datacol">{% trans "Session state" %}</th>
<th class="datacol">{% trans "Session grade" %}</th>
{% endif %}
<th class="datacol">{% trans "Session state" %}</th>
<th class="datacol">{% trans "Session grade" %}</th>
<th class="datacol">{% trans "Overall grade" %}</th>
</thead>
<tbody>
{% for participation, grade_info in grade_table %}
<tr>
<th class="headcol">
<a href="{% url "relate-view_single_grade" course.identifier participation.id opportunity.id %}"><span class="sensitive">{{ participation.user.username }}</span></a>
</th>
<td class="datacol">
<span class="sensitive">
{{ participation.user.get_full_name }}
</span>
{% if participation.role != participation_role.student %}
({{ participation.role }})
{% endif %}
</td>
{% if view_page_grades %}
{% for page_idx, grade in grade_info.grades %}
<td class="datacol"
{% if page_idx == None or grade == None or grade.percentage == None %}
data-order="-1"
{% else %}
data-order="{{ grade.percentage }}"
{% endif %}
><span class="sensitive">
{% if page_idx == None %}
&mdash;
{% else %}
<a href="{% url "relate-grade_flow_page" course.identifier grade_info.flow_session.id page_idx %}">
{% if grade != None and grade.percentage != None %}
{{ grade.percentage|floatformat:1 }}%
<a href="{% url "relate-view_single_grade" course.identifier participation.id opportunity.id %}"><span class="sensitive">
{% if not pperm.view_participant_masked_profile %}
{{ participation.user.username }}
{% else %}
- &#8709; -
{% if participation.user == user %}{% trans "Me" %}{% else %}{{ participation.user.get_masked_profile }}{% endif %}
{% endif %}
</span></a>
{% if pperm.view_participant_masked_profile %}
{% if participation|has_permission:"view_gradebook" %}
({{ participation.get_role_desc }})
{% endif %}
</a>
{% endif %}
</span>
</td>
{% endfor %}
</th>
{% if not pperm.view_participant_masked_profile %}
<td class="datacol">
<span class="sensitive">
{{ participation.user.get_full_name }}
</span>
{% if participation|has_permission:"view_gradebook" %}
({{ participation.get_role_desc }})
{% endif %}
</td>
{% endif %}
<td class="datacol" data-order="{{ grade_info.flow_session.in_progress }}">
{% if grade_info.flow_session %}
{% include "course/flow-session-state.html" with flow_session=grade_info.flow_session %}
{% if not flow_session.in_progress %}
({{ grade_info.flow_session.completion_time }})
{% endif %}
{% if grade_info.flow_session.access_rules_tag %}
({% trans "Rules tag" %}: <tt>{{ grade_info.flow_session.access_rules_tag }}</tt>)
{% endif %}
{% if opportunity.flow_id %}
{% if view_page_grades %}
{% for page_idx, grade in grade_info.grades %}
<td class="datacol"
{% if page_idx == None or grade == None or grade.percentage == None %}
data-order="-1"
{% else %}
data-order="{{ grade.percentage }}"
{% endif %}
><span class="sensitive">
{% if page_idx == None %}
&mdash;
{% else %}
<a href="{% url "relate-grade_flow_page" course.identifier grade_info.flow_session.id page_idx %}">
{% if grade != None and grade.percentage != None %}
{{ grade.percentage|floatformat:"-2" }}%
{% else %}
- &#8709; -
{% endif %}
</a>
{% endif %}
</span>
</td>
{% endfor %}
{% endif %}
</td>
<td class="datacol" data-order="{{ grade_info.flow_session.points }}">
{% if grade_info.flow_session %}
<td class="datacol"
{% if not grade_info.flow_session %}
data-order="-1"
{% elif grade_info.flow_session.in_progress %}
{% if not grade_info.has_finished_session %}
data-order="0"
{% elif grade_info.grade_state_machine.percentage == None %}
data-order="1"
{% elif grade_info.grade_state_machine.percentage <= 0 %}
data-order="2"
{% else %}
data-order="3"
{% endif %}
{% elif grade_info.grade_state_machine.percentage <= 0 %}
data-order="2"
{% else %}
data-order="3"
{% endif %}
>
{% if grade_info.flow_id %}
{% include "course/flow-session-state.html" with flow_session=grade_info.flow_session %}
{% if grade_info.flow_session %}
{% if not grade_info.flow_session.in_progress %}
({{ grade_info.flow_session.completion_time }})
{% endif %}
{% if grade_info.flow_session.access_rules_tag %}
({% trans "Rules tag" %}: <tt>{{ grade_info.flow_session.access_rules_tag }}</tt>)
{% endif %}
{% endif %}
{% endif %}
</td>
<td class="datacol"
{% if not grade_info.flow_session %}
data-order="-"
{% else %}
data-order="{{ grade_info.flow_session.points }}"
{% endif %}
>
{% if grade_info.flow_session %}
{% if grade_info.flow_session.points != None %}
{% blocktrans trimmed with points=grade_info.flow_session.points|floatformat:1 max_points=grade_info.flow_session.max_points|floatformat:1 %}
{{ points }}/{{ max_points }}
points
{% blocktrans trimmed with points=grade_info.flow_session.points|floatformat:"-2" max_points=grade_info.flow_session.max_points|floatformat:"-2" %}
{{ points }}/{{ max_points }}
points
{% endblocktrans %}
{% endif %}
{% endif %}
</td>
{% endif %}
</td>
{% endif %}
<td class="datacol"
{% if grade_info.grade_state_machine.percentage != None %}
{% if grade_info.grade_state_machine == None %}
data-order="-2"
{% elif grade_info.grade_state_machine.percentage != None %}
data-order="{{ grade_info.grade_state_machine.percentage }}"
{% else %}
data-order="-1"
{% endif %}
>
<a href="{% url "relate-view_single_grade" course.identifier participation.id opportunity.id %}"
><span class="sensitive">{{ grade_info.grade_state_machine.stringify_state }}</span></a>
{% if grade_info.grade_state_machine != None %}
<a href="{% url "relate-view_single_grade" course.identifier participation.id opportunity.id %}">
<span class="sensitive">{{ grade_info.grade_state_machine.stringify_state }}</span></a>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
{% load coursetags %}
{% block page_bottom_javascript_extra %}
{% get_current_js_lang_name as LANG %}
<script type="text/javascript">
var tbl = $("table.gradebook-by-opportunity").dataTable({
......@@ -209,9 +255,9 @@
"paging": false,
"ordering": true,
"columnDefs": [{ type: 'name', targets: 1 }],
"language": {url: '{% static "datatables-i18n/i18n/" %}{{LANG}}.json'},
"language": rlDataTables.getI18nTable('{{ LANG}}'),
} );
new $.fn.dataTable.FixedColumns(tbl);
</script>
{{ block.super }}
{% endblock %}
{% extends "course/course-base.html" %}
{% extends "course/course-datatables.html" %}
{% load i18n %}
{% load static %}
{% block title %}
{% trans "List of Grading Opportunities" %} - {% trans "RELATE" %}
{% endblock %}
{% block header_extra %}
{% include "datatables-header.html" %}
{% trans "List of Grading Opportunities" %} - {{ relate_site_name }}
{% endblock %}
{% block content %}
<h1>{% trans "List of Grading Opportunities" %}</h1>
<a href="{% url "relate-edit_grading_opportunity" course.identifier -1 %}" class="btn btn-default">{% trans "Add grading opportunity" %}</a>
<a href="{% url "relate-edit_grading_opportunity" course.identifier -1 %}" class="btn btn-outline-secondary">{% trans "Add grading opportunity" %}</a>
<table class="table table-striped gradebook-opportunities">
<thead>
......@@ -42,7 +38,7 @@
</td>
{% if pperm.edit_participation %}
<td class="datacol">
<a href="{% url "relate-edit_grading_opportunity" course.identifier opp.id %}" class="btn btn-default btn-xs">{% trans "Edit" %}</a>
<a href="{% url "relate-edit_grading_opportunity" course.identifier opp.id %}" class="btn btn-outline-secondary btn-sm">{% trans "Edit" %}</a>
</td>
{% endif %}
<td class="datacol">
......@@ -60,25 +56,26 @@
>{{ opp.due_time }}</td>
<td class="datacol">
{% if opp.shown_in_participant_grade_book and opp.result_shown_in_participant_grade_book %}
<i class="fa fa-check-square-o"></i>
<i class="bi bi-check-square-o"></i>
{% else %}
<i class="fa fa-square-o"></i>
<i class="bi bi-square"></i>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
{% load coursetags %}
{% block page_bottom_javascript_extra %}
{% get_current_js_lang_name as LANG %}
<script type="text/javascript">
var tbl = $("table.gradebook-opportunities").dataTable({
"scrollCollapse": true,
"paging": false,
"ordering": true,
"language": {url: '{% static "datatables-i18n/i18n/" %}{{LANG}}.json'},
"language": rlDataTables.getI18nTable('{{ LANG}}'),
} );
</script>
{{ block.super }}
{% endblock %}