Added course level lang attribute for LMS added lang attribute to Studio fixed error when trying to get language attribute on course that does not exist simplified code added lang attribure to more places in LMS, added migration for language attribute in course_overview fixing contraints in the database for language attribute added lang attribute to several more places in LMS and Studio added lang attribute to discussion and custom pages; cleaned up code fixed issue that was causing test failures moved lang attribute higher in tree in two places
229 lines
14 KiB
HTML
229 lines
14 KiB
HTML
<%page expression_filter="h"/>
|
|
<%inherit file="/main.html" />
|
|
<%namespace name='static' file='/static_content.html'/>
|
|
<%def name="online_help_token()"><% return "progress" %></%def>
|
|
<%!
|
|
from course_modes.models import CourseMode
|
|
from certificates.models import CertificateStatuses
|
|
from django.utils.translation import ugettext as _
|
|
from openedx.core.djangolib.markup import HTML, Text
|
|
from django.core.urlresolvers import reverse
|
|
from django.conf import settings
|
|
from django.utils.http import urlquote_plus
|
|
%>
|
|
<%block name="bodyclass">view-in-course view-progress</%block>
|
|
|
|
<%block name="headextra">
|
|
<%static:css group='style-course-vendor'/>
|
|
<%static:css group='style-course'/>
|
|
</%block>
|
|
|
|
|
|
<%namespace name="progress_graph" file="/courseware/progress_graph.js"/>
|
|
|
|
<%block name="pagetitle">${_("{course_number} Progress").format(course_number=course.display_number_with_default)}</%block>
|
|
|
|
<%block name="js_extra">
|
|
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.js')}"></script>
|
|
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.stack.js')}"></script>
|
|
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.symbol.js')}"></script>
|
|
<script type="text/javascript" src="${static.url('js/courseware/certificates_api.js')}"></script>
|
|
<script type="text/javascript" src="${static.url('js/courseware/credit_progress.js')}"></script>
|
|
<script>
|
|
## This JavaScript is being HTML-escaped because it historically has, and it is not clear what
|
|
## the correct syntax is. For safety, maintain the previous behavior.
|
|
## safe-lint: disable=mako-invalid-js-filter
|
|
${progress_graph.body(grade_summary, course.grade_cutoffs, "grade-detail-graph", not course.no_grade, not course.no_grade)}
|
|
</script>
|
|
</%block>
|
|
|
|
<%include file="/courseware/course_navigation.html" args="active_page='progress'" />
|
|
|
|
<main id="main" aria-label="Content" tabindex="-1">
|
|
<div class="container">
|
|
<div class="profile-wrapper">
|
|
<section class="course-info" id="course-info-progress"
|
|
% if getattr(course, 'language'):
|
|
lang="${course.language}"
|
|
% endif
|
|
>
|
|
% if staff_access and studio_url is not None:
|
|
<div class="wrap-instructor-info">
|
|
<a class="instructor-info-action studio-view" href="${studio_url}">${_("View Grading in studio")}</a>
|
|
</div>
|
|
% endif
|
|
<h2 class="hd hd-2 progress-certificates-title">
|
|
${_("Course Progress for Student '{username}' ({email})").format(username=student.username, email=student.email)}
|
|
</h2>
|
|
|
|
%if certificate_data:
|
|
<div class="wrapper-msg wrapper-auto-cert">
|
|
<div id="errors-info" class="errors-info"></div>
|
|
%if passed:
|
|
<div class="auto-cert-message" id="course-success">
|
|
<div class="has-actions">
|
|
<% post_url = reverse('generate_user_cert', args=[unicode(course.id)]) %>
|
|
<div class="msg-content">
|
|
<h4 class="hd hd-4 title">${certificate_data.title}</h4>
|
|
<p class="copy">${certificate_data.msg}</p>
|
|
</div>
|
|
<div class="msg-actions">
|
|
%if certificate_data.cert_web_view_url:
|
|
<a class="btn" href="${certificate_data.cert_web_view_url}" target="_blank">${_("View Certificate")} <span class="sr">${_("Opens in a new browser window")}</span></a>
|
|
%elif certificate_data.cert_status == CertificateStatuses.downloadable and certificate_data.download_url:
|
|
<a class="btn" href="${certificate_data.download_url}" target="_blank">${_("Download Your Certificate")} <span class="sr">${_("Opens in a new browser window")}</span></a>
|
|
%elif certificate_data.cert_status == CertificateStatuses.requesting:
|
|
<button class="btn generate_certs" data-endpoint="${post_url}" id="btn_generate_cert">${_('Request Certificate')}</button>
|
|
%endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
%endif
|
|
</div>
|
|
%endif
|
|
|
|
%if not course.disable_progress_graph:
|
|
<div class="grade-detail-graph" id="grade-detail-graph"></div>
|
|
%endif
|
|
|
|
% if credit_course_requirements:
|
|
<section class="credit-eligibility">
|
|
<h3 class="hd hd-4 eligibility-heading">${_("Requirements for Course Credit")}</h3>
|
|
<div class="credit-eligibility-container">
|
|
%if credit_course_requirements['eligibility_status'] == 'not_eligible':
|
|
<span class="eligibility_msg">${_("{student_name}, you are no longer eligible for credit in this course.").format(student_name=student.profile.name)}</span>
|
|
%elif credit_course_requirements['eligibility_status'] == 'eligible':
|
|
<span class="eligibility_msg">
|
|
${Text(_("{student_name}, you have met the requirements for credit in this course. {a_start}Go to your dashboard{a_end} to purchase course credit.")).format(
|
|
student_name=student.profile.name,
|
|
a_start=HTML("<a href={url}>").format(url=reverse('dashboard')),
|
|
a_end=HTML("</a>")
|
|
)}
|
|
</span>
|
|
%elif credit_course_requirements['eligibility_status'] == 'partial_eligible':
|
|
<span>${_("{student_name}, you have not yet met the requirements for credit.").format(student_name=student.profile.name)}</span>
|
|
%endif
|
|
|
|
<a href="${settings.CREDIT_HELP_LINK_URL}" class="credit-help">
|
|
<span class="fa fa-question" aria-hidden="true"></span>
|
|
<span class="sr">${_("Information about course credit requirements")}</span>
|
|
</a><br />
|
|
|
|
<div class="requirement-container" data-eligible="${credit_course_requirements['eligibility_status']}">
|
|
%for requirement in credit_course_requirements['requirements']:
|
|
<div class="requirement">
|
|
<div class="requirement-name">
|
|
${_(requirement['display_name'])}
|
|
%if requirement['namespace'] == 'grade':
|
|
<span>${int(requirement['criteria']['min_grade'] * 100)}%</span>
|
|
%endif
|
|
</div>
|
|
<div class="requirement-status">
|
|
%if requirement['status']:
|
|
%if requirement['status'] == 'submitted':
|
|
<span class="requirement-submitted">${_("Verification Submitted")}</span>
|
|
%elif requirement['status'] == 'failed':
|
|
<span class="fa fa-times" aria-hidden="true"></span>
|
|
<span>${_("Verification Failed" )}</span>
|
|
%elif requirement['status'] == 'declined':
|
|
<span class="fa fa-times" aria-hidden="true"></span>
|
|
<span>${_("Verification Declined" )}</span>
|
|
%elif requirement['status'] == 'satisfied':
|
|
<span class="fa fa-check" aria-hidden="true"></span>
|
|
<span class="localized-datetime" data-datetime="${requirement['status_date']}" data-string="${_('Completed by {date}')}" data-timezone="${user_timezone}" data-language="${user_language}"></span>
|
|
%endif
|
|
%else:
|
|
<span class="not-achieve">${_("Upcoming")}</span>
|
|
%endif
|
|
</div>
|
|
</div>
|
|
%endfor
|
|
</div>
|
|
<button class="detail-collapse">
|
|
<span class="fa fa-caret-up" aria-hidden="true"></span>
|
|
<span class="requirement-detail">${_("Less")}</span>
|
|
</button>
|
|
</div>
|
|
</section>
|
|
%endif
|
|
|
|
%if courseware_summary:
|
|
<section class="chapters">
|
|
<h2 class="sr">${_('Details for each chapter')}</h2>
|
|
%for chapter in courseware_summary:
|
|
%if not chapter['display_name'] == "hidden":
|
|
<section aria-labelledby="chapter_${loop.index}">
|
|
<h3 class="hd hd-3" id="chapter_${loop.index}">${ chapter['display_name']}</h3>
|
|
<div class="sections">
|
|
%for section in chapter['sections']:
|
|
<div>
|
|
<%
|
|
earned = section.all_total.earned
|
|
total = section.all_total.possible
|
|
percentageString = "{0:.0%}".format( float(earned)/total) if earned > 0 and total > 0 else ""
|
|
%>
|
|
<h4 class="hd hd-4">
|
|
<a href="${reverse('courseware_section', kwargs=dict(course_id=course.id.to_deprecated_string(), chapter=chapter['url_name'], section=section.url_name))}">
|
|
${ section.display_name}
|
|
%if total > 0 or earned > 0:
|
|
<span class="sr">
|
|
${_("{earned} of {total} possible points").format(earned='{:.3n}'.format(float(earned)), total='{:.3n}'.format(float(total)))}
|
|
</span>
|
|
%endif
|
|
</a>
|
|
%if total > 0 or earned > 0:
|
|
<span> ${"({0:.3n}/{1:.3n}) {2}".format( float(earned), float(total), percentageString )}</span>
|
|
%endif
|
|
</h4>
|
|
<p>
|
|
%if section.format is not None:
|
|
${section.format}
|
|
%endif
|
|
%if section.due is not None:
|
|
<em class="localized-datetime" data-datetime="${section.due}" data-string="${_('due {date}')}" data-timezone="${user_timezone}" data-language="${user_language}"></em>
|
|
%endif
|
|
</p>
|
|
%if len(section.problem_scores.values()) > 0:
|
|
%if section.show_grades(staff_access):
|
|
<dl class="scores">
|
|
<dt class="hd hd-6">${ _("Problem Scores: ") if section.graded else _("Practice Scores: ")}</dt>
|
|
%for score in section.problem_scores.values():
|
|
<dd>${"{0:.3n}/{1:.3n}".format(float(score.earned),float(score.possible))}</dd>
|
|
%endfor
|
|
</dl>
|
|
%else:
|
|
<p class="hide-scores">
|
|
%if section.show_correctness == 'past_due':
|
|
%if section.graded:
|
|
${_("Problem scores are hidden until the due date.")}
|
|
%else:
|
|
${_("Practice scores are hidden until the due date.")}
|
|
%endif
|
|
%else:
|
|
%if section.graded:
|
|
${_("Problem scores are hidden.")}
|
|
%else:
|
|
${_("Practice scores are hidden.")}
|
|
%endif
|
|
%endif
|
|
</p>
|
|
%endif
|
|
%else:
|
|
<p class="no-scores">${_("No problem scores in this section")}</p>
|
|
%endif
|
|
</div>
|
|
%endfor
|
|
</div>
|
|
</section>
|
|
%endif
|
|
%endfor
|
|
</section>
|
|
%endif
|
|
</section>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
<%static:require_module_async module_name="js/dateutil_factory" class_name="DateUtilFactory">
|
|
DateUtilFactory.transform(iterationKey=".localized-datetime");
|
|
</%static:require_module_async>
|