New Feature: Certificates Web View
- SOL-465: Initial implementation of certificates web view and signatories (names/titles) - SOL-718 Close button is working properly - SOL-801 Backbone Signatories Modeling - SOL-803 Underscore template: Editor (Add) - SOL-802 Signatories: Underscore template - Details - SOL-804 Signatories: Underscore template: Editor (Edit) - Add signatory delete Django view - SOL-805 Signatory editor (Delete) - Add Coffeescript router - SOL-716 Jasmine Tests - Added missing minified JS library - client side validation of signatory fields - SOL-390 signatories names - Remove obsolete extends Sass files - input maxlength limiting for signatory information - SOL-389: Course title override - SOL-466: Add capability to upload digitized signatures in Studio - ziafazal: fixed css for upload signature image - ziafazal: completed deletion of signature images - UX-1741: Add initial static rendering/styling for Open edX web certs * creating new global static dir * adding static version of edX UX pattern library assets * adding web certificates static assets * adding static (+abstracted) web certificates rendering * creating two tiers of rendering (base + distinguished) * providing sample assets for certificate rendering * supporting RTL layouts * adding certifcates assests to edX static asset pipeline * temporarily hiding the mozilla open badges share action * wiring print button to print view/page * fixup! addressing conflict artifact in valid cert template * fixup! adding missing %hd-subsection sass extend + components comment clean up * fixup! correcting pattern library .hd-4 font-weight value - SOL-468 Linked Student View for Web View Credential - SOL-467: Add capability to upload organization logos for certificates - SOL-391 / SOL-387: Signatory related info (assets) in certificates web view - kelketek: Fixes for static asset collection in certificate HTML view. - SOL-398 Web View: Public Access - mattdrayer: Post-merge branch stabilization - catong: Initial changes to Studio template and Help config file - ziafazal: Branch stabilizations - SOL-387: Display organization logo on LMS web view - talbs/mattdrayer: Branch Stabilizations - talbs: converting backpack action to use a button HTML element - talbs: revising placeholder assets + their rendering in cert view - mattdrayer: Username web view wireup - SOL-386 Certificate Mode Previews - SOL-905: Make organization logo and signatory signature uneditable - SOL-922: Improve test coverage - SOL-765: Add LinkedIn sharing - [marco] temporary styling adjustment to account for smaller linkedin share image / fake button - SOL-921: Address hardcoded template items - SOL-927: Deleting certificate should delete org logo image also * updated invalid template * removed hr * fix invalid certificate error - clrux: Add i18n to certificate templates and partials - mattdrayer: Pylint violations - SOL-920 Certificate Activation/Deactivation - mattdrayer: Added LMS support - SOL-932: Fix preview mode support in certificate view - SOL-934: Fixed bug reported and broken tests - SOL-935 removed the 'valid' word from web view title - talbs: RTL support updates/fixes * revising certificate type icon/name vertical alignment * removing unused older certificate template * revising styling for message/banner actions * abstracting accomplishment type to use course mode + adding in honor/verified-specific placeholders - mattdrayer: JSHint violations
This commit is contained in:
97
cms/templates/certificates.html
Normal file
97
cms/templates/certificates.html
Normal file
@@ -0,0 +1,97 @@
|
||||
<%inherit file="base.html" />
|
||||
<%def name="online_help_token()"><% return "certificates" %></%def>
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
<%! import json %>
|
||||
<%!
|
||||
from contentstore import utils
|
||||
from django.utils.translation import ugettext as _
|
||||
%>
|
||||
|
||||
<%block name="title">${_("Course Certificates")}</%block>
|
||||
<%block name="bodyclass">is-signedin course view-certificates</%block>
|
||||
|
||||
<%block name="header_extras">
|
||||
% for template_name in ["certificate-details", "certificate-editor", "signatory-editor", "signatory-details", "basic-modal", "modal-button", "list", "upload-dialog", "certificate-web-preview"]:
|
||||
<script type="text/template" id="${template_name}-tpl">
|
||||
<%static:include path="js/${template_name}.underscore" />
|
||||
</script>
|
||||
% endfor
|
||||
</%block>
|
||||
|
||||
<%block name="jsextra">
|
||||
<script type="text/javascript">
|
||||
window.CMS = window.CMS || {};
|
||||
CMS.URL = CMS.URL || {};
|
||||
CMS.URL.UPLOAD_ASSET = '${upload_asset_url}';
|
||||
</script>
|
||||
</%block>
|
||||
|
||||
<%block name="requirejs">
|
||||
require(["js/certificates/factories/certificates_page_factory"], function(CertificatesPageFactory) {
|
||||
CertificatesPageFactory(${json.dumps(certificates)}, "${certificate_url}", "${course_outline_url}", ${json.dumps(course_modes)}, ${json.dumps(certificate_web_view_url)}, ${json.dumps(is_active)}, ${json.dumps(certificate_activation_handler_url)} );
|
||||
});
|
||||
</%block>
|
||||
|
||||
<%block name="content">
|
||||
<div class="wrapper-mast wrapper">
|
||||
<header class="mast has-actions has-subtitle">
|
||||
<h1 class="page-header">
|
||||
<small class="subtitle">${_("Settings")}</small>
|
||||
<span class="sr">> </span>${_("Certificates")}
|
||||
</h1>
|
||||
<div class="preview-certificate nav-actions"></div>
|
||||
</header>
|
||||
</div>
|
||||
|
||||
<div class="wrapper-content wrapper">
|
||||
<section class="content">
|
||||
<article class="content-primary" role="main">
|
||||
<div class="wrapper-certificates certificates-list">
|
||||
<h2 class="sr title">${_("Certificates")}</h2>
|
||||
% if certificates is None:
|
||||
<div class="notice notice-incontext notice-moduledisabled">
|
||||
<p class="copy">
|
||||
${_("This module is not enabled.")}
|
||||
</p>
|
||||
</div>
|
||||
% else:
|
||||
<div class="ui-loading">
|
||||
<p><span class="spin"><i class="icon fa fa-refresh" aria-hidden="true"></i></span> <span class="copy">${_("Loading")}</span></p>
|
||||
</div>
|
||||
% endif
|
||||
</div>
|
||||
</article>
|
||||
<aside class="content-supplementary" role="complementary">
|
||||
<div class="bit">
|
||||
<div class="certificates-doc">
|
||||
<h2 class="title-3">${_("Certificates")}</h2>
|
||||
<p>${_("Upon successful completion of your course, learners receive a certificate to acknowledge their accomplishment. Course team members with the Admin role in Studio can create course certificates based on templates that exist for your organization.")}</p>
|
||||
<p>${_("Course team members with the Admin role can also add signatory names for a certificate, and upload assets including signature image files for signatories. {em_start}Note:{em_end} Signature images are used only for verified certificates.").format(em_start='<strong>', em_end="</strong>")}</p>
|
||||
<p>${_("Click {em_start}New Certificate{em_end} to add a new certificate. To edit a certficate, hover over its box and click {em_start}Edit{em_end}. You can delete a certificate only if it has not been issued to a learner. To delete a certificate, hover over its box and click the delete icon.").format(em_start="<strong>", em_end="</strong>")}</p>
|
||||
<p><a href="${get_online_help_info(online_help_token())['doc_url']}" target="_blank" class="button external-help-button">${_("Learn More")}</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bit">
|
||||
% if context_course:
|
||||
<%
|
||||
details_url = utils.reverse_course_url('settings_handler', context_course.id)
|
||||
grading_url = utils.reverse_course_url('grading_handler', context_course.id)
|
||||
course_team_url = utils.reverse_course_url('course_team_handler', context_course.id)
|
||||
advanced_settings_url = utils.reverse_course_url('advanced_settings_handler', context_course.id)
|
||||
%>
|
||||
<h2 class="title-3">${_("Other Course Settings")}</h2>
|
||||
<nav class="nav-related" aria-label="${_('Other Course Settings')}">
|
||||
<ul>
|
||||
<li class="nav-item"><a href="${details_url}">${_("Details & Schedule")}</a></li>
|
||||
<li class="nav-item"><a href="${grading_url}">${_("Grading")}</a></li>
|
||||
<li class="nav-item"><a href="${course_team_url}">${_("Course Team")}</a></li>
|
||||
<li class="nav-item"><a href="${advanced_settings_url}">${_("Advanced Settings")}</a></li>
|
||||
<li class="nav-item"><a href="${utils.reverse_course_url('group_configurations_list_handler', context_course.id)}">${_("Group Configurations")}</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
% endif
|
||||
</div>
|
||||
</aside>
|
||||
</section>
|
||||
</div>
|
||||
</%block>
|
||||
40
cms/templates/js/certificate-details.underscore
Normal file
40
cms/templates/js/certificate-details.underscore
Normal file
@@ -0,0 +1,40 @@
|
||||
<div class="collection-details wrapper-certificate">
|
||||
<header class="collection-header">
|
||||
<h3 class="sr title">
|
||||
<%= name %>
|
||||
</h3>
|
||||
</header>
|
||||
|
||||
<ol class="collection-info certificate-info certificate-info-<% if(showDetails){ print('block'); } else { print('inline'); } %>">
|
||||
<% if (!_.isUndefined(id)) { %>
|
||||
<li class="sr certificate-id">
|
||||
<span class="certificate-label"><%= gettext('ID') %>: </span>
|
||||
<span class="certificate-value"><%= id %></span>
|
||||
</li>
|
||||
<% } %>
|
||||
<% if (showDetails) { %>
|
||||
<header>
|
||||
<span class="title"><%= gettext("Certificate Details") %></span>
|
||||
</header>
|
||||
<% if (course_title) { %>
|
||||
<div class="course-title-override">
|
||||
<span class="certificate-label"><%= gettext('Course Title Override') %>: </span>
|
||||
<span class="certificate-value"><%= course_title %></span>
|
||||
</div>
|
||||
<% } %>
|
||||
<header style='margin-top: 30px;'>
|
||||
<span class="title"><%= gettext("Certificate Signatories") %></span>
|
||||
</header>
|
||||
<div class="signatory-details-list"></div>
|
||||
<% } %>
|
||||
</ol>
|
||||
|
||||
<ul class="actions certificate-actions">
|
||||
<li class="action action-edit">
|
||||
<button class="edit"><i class="icon fa fa-pencil" aria-hidden="true"></i> <%= gettext("Edit") %></button>
|
||||
</li>
|
||||
<li class="action action-delete wrapper-delete-button" data-tooltip="<%= gettext('Delete') %>">
|
||||
<button class="delete action-icon"><i class="icon fa fa-trash-o" aria-hidden="true"></i><span><%= gettext("Delete") %></span></button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
57
cms/templates/js/certificate-editor.underscore
Normal file
57
cms/templates/js/certificate-editor.underscore
Normal file
@@ -0,0 +1,57 @@
|
||||
<form class="collection-edit-form certificate-edit-form">
|
||||
<div aria-live="polite">
|
||||
<% if (error && error.message) { %>
|
||||
<div class="certificate-edit-error message message-status message-status error is-shown" name="certificate-edit-error">
|
||||
<%= gettext(error.message) %>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="wrapper-form">
|
||||
<fieldset class="collection-fields certificate-fields">
|
||||
<legend class="sr"><%= gettext("Certificate Information") %></legend>
|
||||
<div class="sr input-wrap field text required add-collection-name add-certificate-name <% if(error && error.attributes && error.attributes.name) { print('error'); } %>">
|
||||
<label for="certificate-name-<%= uniqueId %>"><%= gettext("Certificate Name") %></label>
|
||||
<input id="certificate-name-<%= uniqueId %>" class="collection-name-input input-text" name="certificate-name" type="text" placeholder="<%= gettext("Name of the certificate") %>" value="<%= name %>" aria-describedby="certificate-name-<%=uniqueId %>-tip" />
|
||||
<span id="certificate-name-<%= uniqueId %>-tip" class="tip tip-stacked"><%= gettext("Name of the certificate") %></span>
|
||||
</div>
|
||||
<div class="sr input-wrap field text add-certificate-description">
|
||||
<label for="certificate-description-<%= uniqueId %>"><%= gettext("Description") %></label>
|
||||
<textarea id="certificate-description-<%= uniqueId %>" class="certificate-description-input text input-text" name="certificate-description" placeholder="<%= gettext("Description of the certificate") %>" aria-describedby="certificate-description-<%=uniqueId %>-tip"><%= description %></textarea>
|
||||
<span id="certificate-description-<%= uniqueId %>-tip" class="tip tip-stacked"><%= gettext("Description of the certificate") %></span>
|
||||
</div>
|
||||
<div class="input-wrap field text add-certificate-course-title">
|
||||
<label for="certificate-course-title-<%= uniqueId %>"><%= gettext("Course Title Override") %></label>
|
||||
<input id="certificate-course-title-<%= uniqueId %>" class="certificate-course-title-input input-text" name="certificate-course-title" type="text" placeholder="<%= gettext("Course title") %>" value="<%= course_title %>" aria-describedby="certificate-course-title-<%=uniqueId %>-tip" />
|
||||
<span id="certificate-course-title-<%= uniqueId %>-tip" class="tip tip-stacked"><%= gettext("Title of the course") %></span>
|
||||
</div>
|
||||
<div class="input-wrap field text add-org-logo">
|
||||
<label for="certificate-org-logo-<%= uniqueId %>"><%= gettext("Organization Logo") %></label>
|
||||
<div class="current-org-logo" <% if (org_logo_path == "") { print('style="display:none"'); } %>><span class="wrapper-org-logo"><img class="org-logo" src="<%= org_logo_path %>" alt="Organization Logo"></span></div>
|
||||
<div class="org-logo-upload-wrapper">
|
||||
<div class="org-logo-upload-input-wrapper">
|
||||
<input id="certificate-org-logo-<%= uniqueId %>" class="collection-name-input input-text org-logo-input" name="org-logo-path" type="text" placeholder="<%= gettext("Path to organization logo") %>" value="<%= org_logo_path %>" aria-describedby="certificate-org-logo-<%=uniqueId %>-tip" readonly />
|
||||
<span id="certificate-org-logo-<%=uniqueId %>-tip" class="tip tip-stacked"><%= gettext("Maximum logo height 125px, width variable") %></span>
|
||||
</div>
|
||||
<button type="button" class="action action-upload-org-logo">Upload Organization Logo</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<header>
|
||||
<span class="title"><%= gettext("Certificate Signatories") %></legend>
|
||||
</header>
|
||||
<div class="signatory-edit-list"> </div>
|
||||
<span>
|
||||
<button class="action action-add-signatory" type="button"><%= gettext("Add Signatory") %></button>
|
||||
<span class="tip tip-stacked"><%= gettext("(Up to 4 signatories are allowed for a certificate)") %></span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button class="action action-primary" type="submit"><% if (isNew) { print(gettext("Create")) } else { print(gettext("Save")) } %></button>
|
||||
<button class="action action-secondary action-cancel"><%= gettext("Cancel") %></button>
|
||||
<% if (!isNew) { %>
|
||||
<span class="wrapper-delete-button">
|
||||
<a class="button action-delete delete" href="#"><%= gettext("Delete") %></a>
|
||||
</span>
|
||||
<% } %>
|
||||
</div>
|
||||
</form>
|
||||
17
cms/templates/js/certificate-web-preview.underscore
Normal file
17
cms/templates/js/certificate-web-preview.underscore
Normal file
@@ -0,0 +1,17 @@
|
||||
<label for="course-modes"><%= gettext("Choose mode") %></label>
|
||||
<select id="course-modes">
|
||||
<% _.each(course_modes, function(course_mode) { %>
|
||||
<option value= "<%= course_mode %>"><%= course_mode %></option>
|
||||
<% }); %>
|
||||
</select>
|
||||
<a href=<%= certificate_web_view_url %> class="button preview-certificate-link" target="_blank">
|
||||
<%= gettext("Preview Certificate") %>
|
||||
</a>
|
||||
<button class="button activate-cert">
|
||||
<span>
|
||||
<% if(!is_active) { %>
|
||||
<%= gettext("Activate") %></span>
|
||||
<% } else { %>
|
||||
<%= gettext("Deactivate") %></span>
|
||||
<% } %>
|
||||
</button>
|
||||
@@ -11,7 +11,7 @@
|
||||
<% } else { %>
|
||||
<div class="list-items"></div>
|
||||
<% if (!isEditing) { %>
|
||||
<button class="action action-add">
|
||||
<button class="action action-add <% if(!canCreateNewItem) {%> action-add-hidden <% }%>" >
|
||||
<i class="icon fa fa-plus"></i>
|
||||
<%- interpolate(
|
||||
gettext('New %(item_type)s'), {item_type: itemCategoryDisplayName}, true
|
||||
|
||||
22
cms/templates/js/signatory-details.underscore
Normal file
22
cms/templates/js/signatory-details.underscore
Normal file
@@ -0,0 +1,22 @@
|
||||
<div class="signatory-panel-default">
|
||||
<div class="actions certificate-actions signatory-panel-edit">
|
||||
<span class="action action-edit-signatory">
|
||||
<a href="javascript:void(0);" class="edit-signatory"><i class="icon fa fa-pencil" aria-hidden="true"></i> <%= gettext("Edit") %></a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="signatory-panel-header">Signatory <%= signatory_number %> </div>
|
||||
<div class="signatory-panel-body">
|
||||
<div>
|
||||
<span class="signatory-name-label"><%= gettext("Name") %>: </span>
|
||||
<span class="signatory-name-value"><%= name %></span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="signatory-title-label"><%= gettext("Title") %>: </span>
|
||||
<span class="signatory-title-value"><%= title %></span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="signatory-organization-label"><%= gettext("Organization") %>: </span>
|
||||
<span class="signatory-organization-value"><%= organization %></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
61
cms/templates/js/signatory-editor.underscore
Normal file
61
cms/templates/js/signatory-editor.underscore
Normal file
@@ -0,0 +1,61 @@
|
||||
<div class="signatory-panel-default">
|
||||
|
||||
<% if (!is_editing_all_collections) { %>
|
||||
<a class="signatory-panel-close" href="javascript:void(0);" data-tooltip="Close">
|
||||
<i class="icon fa fa-close" aria-hidden="true"></i>
|
||||
<span class="sr action-button-text"><%= gettext("Close") %></span>
|
||||
</a>
|
||||
<a class="signatory-panel-save" href="javascript:void(0);" data-tooltip="Save">
|
||||
<i class="icon fa fa-save" aria-hidden="true"></i>
|
||||
<span class="sr action-button-text"><%= gettext("Save") %></span>
|
||||
</a>
|
||||
<% } else if (signatories_count > 1 && (total_saved_signatories > 1 || isNew) ) { %>
|
||||
<a class="signatory-panel-delete" href="#" data-tooltip="Delete">
|
||||
<i class="icon fa fa-trash-o" aria-hidden="true"></i>
|
||||
<span class="sr action-button-text"><%= gettext("Delete") %></span>
|
||||
</a>
|
||||
<% } %>
|
||||
<div class="signatory-panel-header">Signatory <%= signatory_number %></div>
|
||||
<div class="signatory-panel-body">
|
||||
<fieldset class="collection-fields signatory-fields">
|
||||
<legend class="sr"><%= gettext("Certificate Signatory Configuration") %></legend>
|
||||
<div class="input-wrap field text add-signatory-name <% if(error && error.name) { print('error'); } %>">
|
||||
<label for="signatory-name-<%= signatory_number %>"><%= gettext("Name ") %></label>
|
||||
<input id="signatory-name-<%= signatory_number %>" class="collection-name-input input-text signatory-name-input" name="signatory-name" type="text" placeholder="<%= gettext("Name of the signatory") %>" value="<%= name %>" aria-describedby="signatory-name-<%= signatory_number %>-tip" maxlength="40" />
|
||||
<span id="signatory-name-<%= signatory_number %>-tip" class="tip tip-stacked"><%= gettext("Maximum 40 characters") %></span>
|
||||
<% if(error && error.name) { %>
|
||||
<span class="message-error"><%= error.name %></span>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="input-wrap field text add-signatory-title <% if(error && error.title) { print('error'); } %>">
|
||||
<label for="signatory-title-<%= signatory_number %>"><%= gettext("Title ") %></label>
|
||||
<textarea id="signatory-title-<%= signatory_number %>" class="collection-name-input text input-text signatory-title-input" name="signatory-title" cols="40" rows="2" placeholder="<%= gettext("Title of the signatory") %>" aria-describedby="signatory-title-<%= signatory_number %>-tip" maxlength="80"><%= title %></textarea>
|
||||
<span id="signatory-title-<%= signatory_number %>-tip" class="tip tip-stacked"><%= gettext("2 Lines, 40 characters each") %></span>
|
||||
<% if(error && error.title) { %>
|
||||
<span class="message-error"><%= error.title %></span>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="input-wrap field text add-signatory-organization <% if(error && error.organization) { print('error'); } %>">
|
||||
<label for="signatory-organization-<%= signatory_number %>"><%= gettext("Organization ") %></label>
|
||||
<input id="signatory-organization-<%= signatory_number %>" class="collection-name-input input-text signatory-organization-input" name="signatory-organization" type="text" placeholder="<%= gettext("Organization of the signatory") %>" value="<%= organization %>" aria-describedby="signatory-organization-<%= signatory_number %>-tip" maxlength="40" />
|
||||
<span id="signatory-organization-<%= signatory_number %>-tip" class="tip tip-stacked"><%= gettext("Maximum 40 characters") %></span>
|
||||
<% if(error && error.organization) { %>
|
||||
<span class="message-error"><%= error.organization %></span>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="input-wrap field text add-signatory-signature">
|
||||
<label for="signatory-signature-<%= signatory_number %>"><%= gettext("Signature Image") %></label>
|
||||
<% if (signature_image_path != "") { %>
|
||||
<div class="current-signature-image"><span class="wrapper-signature-image"><img class="signature-image" src="<%= signature_image_path %>" alt="Signature Image"></span></div>
|
||||
<% } %>
|
||||
<div class="signature-upload-wrapper">
|
||||
<div class="signature-upload-input-wrapper">
|
||||
<input id="signatory-signature-<%= signatory_number %>" class="collection-name-input input-text signatory-signature-input" name="signatory-signature-url" type="text" placeholder="<%= gettext("Path to Signature Image") %>" value="<%= signature_image_path %>" aria-describedby="signatory-signature-<%= signatory_number %>-tip" readonly />
|
||||
<span id="signatory-signature-<%= signatory_number %>-tip" class="tip tip-stacked"><%= gettext("Image must be 450px X 150px transparent PNG") %></span>
|
||||
</div>
|
||||
<button type="button" class="action action-upload-signature">Upload Signature Image</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
@@ -3,6 +3,7 @@
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext as _
|
||||
from contentstore.context_processors import doc_url
|
||||
from student.roles import CourseCreatorRole, CourseInstructorRole, CourseStaffRole
|
||||
%>
|
||||
<%page args="online_help_token"/>
|
||||
|
||||
@@ -34,6 +35,7 @@
|
||||
grading_url = reverse('contentstore.views.grading_handler', kwargs={'course_key_string': unicode(course_key)})
|
||||
advanced_settings_url = reverse('contentstore.views.advanced_settings_handler', kwargs={'course_key_string': unicode(course_key)})
|
||||
tabs_url = reverse('contentstore.views.tabs_handler', kwargs={'course_key_string': unicode(course_key)})
|
||||
certificates_url = reverse('contentstore.views.certificates.certificates_list_handler', kwargs={'course_key_string': unicode(course_key)})
|
||||
%>
|
||||
<h2 class="info-course">
|
||||
<span class="sr">${_("Current Course:")}</span>
|
||||
@@ -98,6 +100,15 @@
|
||||
<li class="nav-item nav-course-settings-advanced">
|
||||
<a href="${advanced_settings_url}">${_("Advanced Settings")}</a>
|
||||
</li>
|
||||
% if settings.FEATURES.get('CERTIFICATES_HTML_VIEW', False) and \
|
||||
(user.is_superuser or user.is_staff or \
|
||||
CourseCreatorRole(course_key).has_user(user) or \
|
||||
CourseInstructorRole(course_key).has_user(user) or \
|
||||
CourseStaffRole(course_key).has_user(user)):
|
||||
<li class="nav-item nav-course-settings-certificates">
|
||||
<a href="${certificates_url}">${_("Certificates")}</a>
|
||||
</li>
|
||||
% endif
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user