fix: progress tracking
This commit is contained in:
@@ -628,16 +628,6 @@ input[type=checkbox] {
|
|||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lesson-progress {
|
|
||||||
background: #BFDDF7;
|
|
||||||
padding: 4px 8px 4px;
|
|
||||||
font-size: 10px;
|
|
||||||
line-height: 120%;
|
|
||||||
margin-left: 1rem;
|
|
||||||
border-radius: var(--border-radius-md);
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile-page {
|
.profile-page {
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,11 +70,14 @@
|
|||||||
data-index="{{ lesson_index }}" data-course="{{ course.name }}" data-chapter="{{ chapter }}"
|
data-index="{{ lesson_index }}" data-course="{{ course.name }}" data-chapter="{{ chapter }}"
|
||||||
{% if lesson.name %} data-lesson="{{ lesson.name }}" {% endif %}
|
{% if lesson.name %} data-lesson="{{ lesson.name }}" {% endif %}
|
||||||
>{% if lesson.title %}{{ lesson.title }}{% endif %}</div>
|
>{% if lesson.title %}{{ lesson.title }}{% endif %}</div>
|
||||||
<span class="indicator-pill green {{ hide if get_progress(course.name, lesson.name) != 'Complete' else ''}}">{{ _("COMPLETED") }}</span>
|
|
||||||
|
{% if get_progress(course.name, lesson.name) == 'Complete' %}
|
||||||
|
<span id="status-indicator" class="indicator-pill green">{{ _("COMPLETED") }}</span>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<!-- Edit Button -->
|
<!-- Edit Button -->
|
||||||
{% if (is_instructor or has_course_moderator_role()) and not lesson.edit_mode %}
|
{% if (is_instructor or has_course_moderator_role()) and not lesson.edit_mode %}
|
||||||
<button class="button is-default button-links ml-2 btn-edit"> {{ _("Edit") }} </button>
|
<button class="btn btn-secondary btn-sm ml-2 btn-edit"> {{ _("Edit") }} </button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -145,42 +148,23 @@
|
|||||||
|
|
||||||
<!-- Pagination -->
|
<!-- Pagination -->
|
||||||
{% macro pagination(prev_url, next_url) %}
|
{% macro pagination(prev_url, next_url) %}
|
||||||
<div class="lesson-pagination">
|
<div class="lesson-pagination">
|
||||||
<div>
|
|
||||||
{% if prev_url %}
|
{% if prev_url %}
|
||||||
<a class="btn btn-secondary dark-links prev" href="{{ prev_url }}">
|
<div>
|
||||||
{{ _("Previous") }}
|
<a class="btn btn-secondary btn-sm prev" href="{{ prev_url }}">
|
||||||
</a>
|
{{ _("Previous") }}
|
||||||
{% endif %}
|
</a>
|
||||||
</div>
|
|
||||||
|
|
||||||
{% set progress = get_progress(course.name, lesson.name) %}
|
|
||||||
|
|
||||||
{% if not is_mentor(course.name, frappe.session.user) and membership %}
|
|
||||||
<div class="custom-checkbox {% if progress == 'Complete' %} hide {% endif %}">
|
|
||||||
<label class="quiz-label">
|
|
||||||
<input class="mark-progress" type="checkbox" checked>
|
|
||||||
<img class="empty-checkbox" />
|
|
||||||
<span class="small">{{ _("Mark as complete on moving to the next lesson") }}</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div>
|
|
||||||
{% if not is_mentor(course.name, frappe.session.user) and membership %}
|
|
||||||
<div class="btn btn-default mark-progress {{ progress }} {% if progress == 'Incomplete' or progress == None %} hide {% endif %}"
|
|
||||||
data-progress="Incomplete">
|
|
||||||
{{ _("Mark as Incomplete") }}
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<a class="btn btn-primary next ml-2 {% if not next_url and (membership.progress|int == 100 or is_instructor) %} hide {% endif %}"
|
{% if next_url %}
|
||||||
{% if next_url %} data-href="{{ next_url }}" {% endif %} href="">
|
<div>
|
||||||
{% if next_url %} {{ _("Next") }} {% else %} {{ _("Mark as Complete") }} {% endif %}
|
<a class="btn btn-primary btn-sm next ml-2 " href="{{ next_url }}">
|
||||||
</a>
|
{{ _("Next") }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
|
||||||
@@ -261,52 +245,6 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
<!-- <table class="table w-100">
|
|
||||||
<tr>
|
|
||||||
<th style="width: 20%;"> {{ _("Content Type") }} </th>
|
|
||||||
<th style="width: 40%;"> {{ _("Syntax") }} </th>
|
|
||||||
<th> {{ _("Description") }} </th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
{{ _("YouTube Video") }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{% raw %} {{ YouTubeVideo('Video ID') }} {% endraw %}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span>
|
|
||||||
{{ _("Copy and paste the syntax in the editor. Replace 'Video ID' with the embed source
|
|
||||||
that YouTube provides. To get the source, follow the steps mentioned below.") }}
|
|
||||||
</span>
|
|
||||||
<ul class="p-4">
|
|
||||||
<li>
|
|
||||||
{{ _("Upload the video on youtube.") }}
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
{{ _("When you share a youtube video, it shows an option called Embed.") }}
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
{{ _("On clicking it, it provides an iframe. Copy the source (src) of the iframe and
|
|
||||||
paste it here.") }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
{{ _("Quiz") }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{% raw %} {{ Quiz('Quiz ID') }} {% endraw %}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{% set quiz_link = "<a href='/quizzes'> Quiz List </a>" %}
|
|
||||||
{{ _("Copy and paste the syntax in the editor. Replace 'Quiz ID' with the Id of the Quiz.
|
|
||||||
You can get the Id of the quiz from the {0}.").format(quiz_link) }}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table> -->
|
|
||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
frappe.ready(() => {
|
frappe.ready(() => {
|
||||||
|
|
||||||
|
this.marked_as_complete = false;
|
||||||
|
|
||||||
localStorage.removeItem($("#quiz-title").data("name"));
|
localStorage.removeItem($("#quiz-title").data("name"));
|
||||||
|
|
||||||
fetch_assignments();
|
fetch_assignments();
|
||||||
@@ -7,15 +9,15 @@ frappe.ready(() => {
|
|||||||
save_current_lesson();
|
save_current_lesson();
|
||||||
|
|
||||||
$(".option").click((e) => {
|
$(".option").click((e) => {
|
||||||
enable_check(e);
|
enable_check(e);
|
||||||
})
|
|
||||||
|
|
||||||
$(".mark-progress").click((e) => {
|
|
||||||
mark_progress(e);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$(".next").click((e) => {
|
$(window).scroll(() => {
|
||||||
mark_progress(e);
|
let self = this;
|
||||||
|
if (!$("#status-indicator").length && !self.marked_as_complete && $(".title").hasClass("is-member")) {
|
||||||
|
self.marked_as_complete = true;
|
||||||
|
mark_progress();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#summary").click((e) => {
|
$("#summary").click((e) => {
|
||||||
@@ -112,6 +114,7 @@ const mark_active_question = (e = undefined) => {
|
|||||||
|
|
||||||
let current_index = $(".active-question").attr("data-qt-index") || 0;
|
let current_index = $(".active-question").attr("data-qt-index") || 0;
|
||||||
let next_index = parseInt(current_index) + 1;
|
let next_index = parseInt(current_index) + 1;
|
||||||
|
|
||||||
$(".question").addClass("hide").removeClass("active-question");
|
$(".question").addClass("hide").removeClass("active-question");
|
||||||
$(`.question[data-qt-index='${next_index}']`).removeClass("hide").addClass("active-question");
|
$(`.question[data-qt-index='${next_index}']`).removeClass("hide").addClass("active-question");
|
||||||
$(".current-question").text(`${next_index}`);
|
$(".current-question").text(`${next_index}`);
|
||||||
@@ -122,82 +125,34 @@ const mark_active_question = (e = undefined) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const mark_progress = (e) => {
|
const mark_progress = () => {
|
||||||
/* Prevent default only for Next button anchor tag and not for progress checkbox */
|
let status = "Complete"
|
||||||
if ($(e.currentTarget).prop("nodeName") != "INPUT")
|
frappe.call({
|
||||||
e.preventDefault();
|
method: "lms.lms.doctype.course_lesson.course_lesson.save_progress",
|
||||||
else
|
args: {
|
||||||
return;
|
lesson: $(".title").attr("data-lesson"),
|
||||||
|
course: $(".title").attr("data-course"),
|
||||||
const target = $(e.currentTarget).attr("data-progress") ? $(e.currentTarget) : $("input.mark-progress");
|
status: status
|
||||||
const current_status = $(".lesson-progress").hasClass("hide") ? "Incomplete": "Complete";
|
},
|
||||||
|
callback: (data) => {
|
||||||
let status = "Incomplete";
|
change_progress_indicators();
|
||||||
if (target.prop("nodeName") == "INPUT" && target.prop("checked")) {
|
show_certificate_if_course_completed(data);
|
||||||
status = "Complete";
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
if (status != current_status) {
|
|
||||||
frappe.call({
|
|
||||||
method: "lms.lms.doctype.course_lesson.course_lesson.save_progress",
|
|
||||||
args: {
|
|
||||||
lesson: $(".title").attr("data-lesson"),
|
|
||||||
course: $(".title").attr("data-course"),
|
|
||||||
status: status
|
|
||||||
},
|
|
||||||
callback: (data) => {
|
|
||||||
change_progress_indicators(status, e);
|
|
||||||
show_certificate_if_course_completed(data);
|
|
||||||
move_to_next_lesson(status, e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
move_to_next_lesson(status, e);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const change_progress_indicators = (status, e) => {
|
const change_progress_indicators = () => {
|
||||||
if (status == "Complete") {
|
$(".active-lesson .lesson-progress-tick").removeClass("hide");
|
||||||
$(".lesson-progress").removeClass("hide");
|
|
||||||
$(".active-lesson .lesson-progress-tick").removeClass("hide");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$(".lesson-progress").addClass("hide");
|
|
||||||
$(".active-lesson .lesson-progress-tick").addClass("hide");
|
|
||||||
}
|
|
||||||
if (status == "Incomplete" && !$(e.currentTarget).hasClass("next")) {
|
|
||||||
$(e.currentTarget).addClass("hide");
|
|
||||||
$("input.mark-progress").prop("checked", false).closest(".custom-checkbox").removeClass("hide");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const show_certificate_if_course_completed = (data) => {
|
const show_certificate_if_course_completed = (data) => {
|
||||||
if (data.message == 100 && !$(".next").attr("data-next") && $("#certification").hasClass("hide")) {
|
if (data.message == 100 && !$(".next").length && $("#certification").hasClass("hide")) {
|
||||||
$("#certification").removeClass("hide");
|
$("#certification").removeClass("hide");
|
||||||
$(".next").addClass("hide");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const move_to_next_lesson = (status, e) => {
|
|
||||||
if ($(e.currentTarget).hasClass("next") && $(e.currentTarget).attr("data-href")) {
|
|
||||||
window.location.href = $(e.currentTarget).attr("data-href");
|
|
||||||
}
|
|
||||||
else if (status == "Complete") {
|
|
||||||
$("input.mark-progress").closest(".custom-checkbox").addClass("hide");
|
|
||||||
$("div.mark-progress").removeClass("hide");
|
|
||||||
$(".next").addClass("hide");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$("input.mark-progress").closest(".custom-checkbox").removeClass("hide");
|
|
||||||
$("div.mark-progress").addClass("hide");
|
|
||||||
$(".next").removeClass("hide");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const quiz_summary = (e=undefined) => {
|
const quiz_summary = (e=undefined) => {
|
||||||
e && e.preventDefault();
|
e && e.preventDefault();
|
||||||
let quiz_name = $("#quiz-title").data("name");
|
let quiz_name = $("#quiz-title").data("name");
|
||||||
|
|||||||
Reference in New Issue
Block a user