feat: class improvements
This commit is contained in:
@@ -73,21 +73,8 @@ def remove_student(student, class_name):
|
|||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def update_course(class_name, course, value):
|
def remove_course(course, parent):
|
||||||
if cint(value):
|
frappe.db.delete("Class Course", {"name": course, "parent": parent})
|
||||||
doc = frappe.get_doc(
|
|
||||||
{
|
|
||||||
"doctype": "Class Course",
|
|
||||||
"parent": class_name,
|
|
||||||
"course": course,
|
|
||||||
"parenttype": "LMS Class",
|
|
||||||
"parentfield": "courses",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
doc.save()
|
|
||||||
else:
|
|
||||||
frappe.db.delete("Class Course", {"parent": class_name, "course": course})
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
|
|||||||
@@ -1989,8 +1989,8 @@ select {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
/* border: 1px solid var(--gray-200); */
|
border: 1px solid var(--gray-300);
|
||||||
box-shadow: var(--shadow-sm);
|
/* box-shadow: var(--shadow-sm); */
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@@ -112,26 +112,51 @@
|
|||||||
|
|
||||||
|
|
||||||
{% macro CoursesSection(class_info, class_courses, published_courses) %}
|
{% macro CoursesSection(class_info, class_courses, published_courses) %}
|
||||||
<div class="class-course-list">
|
<article>
|
||||||
{% if published_courses | length %}
|
<header class="mb-5">
|
||||||
{% for course in published_courses %}
|
{% if is_moderator %}
|
||||||
{% set checked = course.name in class_courses %}
|
<button class="btn btn-secondary btn-sm btn-add-course pull-right">
|
||||||
<label class="class-course" data-course="{{ course.name }}">
|
{{ _("Add Courses") }}
|
||||||
<input type="checkbox" {% if checked %} checked {% endif %}
|
</button>
|
||||||
{% if not is_moderator %} disabled {% endif %}>
|
{% endif %}
|
||||||
{{ course.title }}
|
<div class="bold-heading">
|
||||||
</label>
|
{{ _("Courses") }}
|
||||||
{% endfor %}
|
</div>
|
||||||
{% endif %}
|
</header>
|
||||||
</div>
|
|
||||||
|
<div>
|
||||||
|
{% for course in class_courses %}
|
||||||
|
<div class="mb-4">
|
||||||
|
<div class="pull-right">
|
||||||
|
<svg class="icon icon-md pull-right btn-remove-course" data-course="{{ course.name }}">
|
||||||
|
<use href="#icon-delete"></use>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{ course.title }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</article>
|
||||||
|
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
|
||||||
{% macro StudentsSection(class_info, class_students) %}
|
{% macro StudentsSection(class_info, class_students) %}
|
||||||
<div class="">
|
<div class="">
|
||||||
{% if is_moderator %}
|
|
||||||
{{ AddStudents() }}
|
<header>
|
||||||
{% endif %}
|
<div class="pull-right">
|
||||||
|
<button class="btn btn-secondary btn-sm btn-add-student">
|
||||||
|
{{ _("Add Students") }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="bold-heading">
|
||||||
|
{{ _("Students") }}
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
{% if class_students | length %}
|
{% if class_students | length %}
|
||||||
<table class="table">
|
<table class="table">
|
||||||
@@ -171,23 +196,13 @@
|
|||||||
|
|
||||||
</table>
|
</table>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p class="text-muted mt-3 ml-5"> {{ _("No Students are added to this class.") }} </p>
|
<p class="text-muted mt-3"> {{ _("No Students are added to this class.") }} </p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
|
||||||
{% macro AddStudents() %}
|
|
||||||
<div class="mb-10">
|
|
||||||
<div class="add-students"></div>
|
|
||||||
<button class="btn btn-primary btn-sm ml-5" id="submit-student">
|
|
||||||
{{ _("Add") }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{% endmacro %}
|
|
||||||
|
|
||||||
|
|
||||||
{% macro LiveClassSection(class_info, live_classes) %}
|
{% macro LiveClassSection(class_info, live_classes) %}
|
||||||
<div>
|
<div>
|
||||||
{{ CreateLiveClass(class_info) }}
|
{{ CreateLiveClass(class_info) }}
|
||||||
@@ -304,3 +319,9 @@
|
|||||||
|
|
||||||
{{ include_script('controls.bundle.js') }}
|
{{ include_script('controls.bundle.js') }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% set classes = frappe.get_all("LMS Class", filters = {
|
||||||
|
"start_date": [">", frappe.utils.getdate()],
|
||||||
|
"title": ["like", "%ERPNext%"]
|
||||||
|
}, fields=["name", "title", "start_date", "end_date"])
|
||||||
|
%}
|
||||||
@@ -1,24 +1,16 @@
|
|||||||
frappe.ready(() => {
|
frappe.ready(() => {
|
||||||
$("#submit-student").click((e) => {
|
$(".btn-add-student").click((e) => {
|
||||||
submit_student(e);
|
show_student_modal(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
$(".remove-student").click((e) => {
|
$(".remove-student").click((e) => {
|
||||||
remove_student(e);
|
remove_student(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
$(".class-course").click((e) => {
|
|
||||||
update_course(e);
|
|
||||||
});
|
|
||||||
|
|
||||||
if ($("#live-class-form").length) {
|
if ($("#live-class-form").length) {
|
||||||
make_live_class_form();
|
make_live_class_form();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($(".add-students").length) {
|
|
||||||
make_add_students_section();
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#open-class-modal").click((e) => {
|
$("#open-class-modal").click((e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
$("#live-class-modal").modal("show");
|
$("#live-class-modal").modal("show");
|
||||||
@@ -27,6 +19,14 @@ frappe.ready(() => {
|
|||||||
$("#create-live-class").click((e) => {
|
$("#create-live-class").click((e) => {
|
||||||
create_live_class(e);
|
create_live_class(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(".btn-add-course").click((e) => {
|
||||||
|
show_course_modal(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".btn-remove-course").click((e) => {
|
||||||
|
remove_course(e);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const submit_student = (e) => {
|
const submit_student = (e) => {
|
||||||
@@ -77,17 +77,6 @@ const remove_student = (e) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const update_course = (e) => {
|
|
||||||
frappe.call({
|
|
||||||
method: "lms.lms.doctype.lms_class.lms_class.update_course",
|
|
||||||
args: {
|
|
||||||
course: $(e.currentTarget).data("course"),
|
|
||||||
value: $(e.currentTarget).children("input").prop("checked") ? 1 : 0,
|
|
||||||
class_name: $(".class-details").data("class"),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const create_live_class = (e) => {
|
const create_live_class = (e) => {
|
||||||
let class_name = $(".class-details").data("class");
|
let class_name = $(".class-details").data("class");
|
||||||
frappe.call({
|
frappe.call({
|
||||||
@@ -353,3 +342,110 @@ const make_add_students_section = () => {
|
|||||||
$(".add-students .form-section:last").removeClass("empty-section");
|
$(".add-students .form-section:last").removeClass("empty-section");
|
||||||
$(".add-students .frappe-control").removeClass("hide-control");
|
$(".add-students .frappe-control").removeClass("hide-control");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const show_course_modal = () => {
|
||||||
|
let course_modal = new frappe.ui.Dialog({
|
||||||
|
title: "Add Course",
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
fieldtype: "Link",
|
||||||
|
options: "LMS Course",
|
||||||
|
label: __("Course"),
|
||||||
|
fieldname: "course",
|
||||||
|
reqd: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
primary_action_label: __("Add"),
|
||||||
|
primary_action(values) {
|
||||||
|
frappe.call({
|
||||||
|
method: "frappe.client.insert",
|
||||||
|
args: {
|
||||||
|
doc: {
|
||||||
|
doctype: "Class Course",
|
||||||
|
course: values.course,
|
||||||
|
parenttype: "LMS Class",
|
||||||
|
parentfield: "courses",
|
||||||
|
parent: $(".class-details").data("class"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
callback(r) {
|
||||||
|
frappe.show_alert(
|
||||||
|
{
|
||||||
|
message: __("Course Added"),
|
||||||
|
indicator: "green",
|
||||||
|
},
|
||||||
|
3
|
||||||
|
);
|
||||||
|
window.location.reload();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
course_modal.hide();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
course_modal.show();
|
||||||
|
};
|
||||||
|
|
||||||
|
const remove_course = (e) => {
|
||||||
|
frappe.call({
|
||||||
|
method: "lms.lms.doctype.lms_class.lms_class.remove_course",
|
||||||
|
args: {
|
||||||
|
course: $(e.target).data("course"),
|
||||||
|
parent: $(".class-details").data("class"),
|
||||||
|
},
|
||||||
|
callback(r) {
|
||||||
|
frappe.show_alert(
|
||||||
|
{
|
||||||
|
message: __("Course Removed"),
|
||||||
|
indicator: "green",
|
||||||
|
},
|
||||||
|
3
|
||||||
|
);
|
||||||
|
window.location.reload();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const show_student_modal = () => {
|
||||||
|
let student_modal = new frappe.ui.Dialog({
|
||||||
|
title: "Add Student",
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
fieldtype: "Link",
|
||||||
|
options: "User",
|
||||||
|
label: __("Student"),
|
||||||
|
fieldname: "student",
|
||||||
|
reqd: 1,
|
||||||
|
filters: {
|
||||||
|
ignore_user_type: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
primary_action_label: __("Add"),
|
||||||
|
primary_action(values) {
|
||||||
|
frappe.call({
|
||||||
|
method: "frappe.client.insert",
|
||||||
|
args: {
|
||||||
|
doc: {
|
||||||
|
doctype: "Class Student",
|
||||||
|
student: values.student,
|
||||||
|
parenttype: "LMS Class",
|
||||||
|
parentfield: "students",
|
||||||
|
parent: $(".class-details").data("class"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
callback(r) {
|
||||||
|
frappe.show_alert(
|
||||||
|
{
|
||||||
|
message: __("Student Added"),
|
||||||
|
indicator: "green",
|
||||||
|
},
|
||||||
|
3
|
||||||
|
);
|
||||||
|
window.location.reload();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
student_modal.hide();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
student_modal.show();
|
||||||
|
};
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ def get_context(context):
|
|||||||
)
|
)
|
||||||
|
|
||||||
context.class_courses = frappe.get_all(
|
context.class_courses = frappe.get_all(
|
||||||
"Class Course", {"parent": class_name}, pluck="course"
|
"Class Course", {"parent": class_name}, ["name", "course", "title"]
|
||||||
)
|
)
|
||||||
|
|
||||||
class_students = frappe.get_all(
|
class_students = frappe.get_all(
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="course-home-headings"> {{ _("All Classes") }} </div>
|
<div class="course-home-headings"> {{ _("All Classes") }} </div>
|
||||||
{% if classes %}
|
{% if past_classes | length or upcoming_classes | length %}
|
||||||
{{ ClassCards(classes) }}
|
{{ ClassTabs(past_classes, upcoming_classes) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="empty-state">
|
<div class="empty-state">
|
||||||
<img class="icon icon-xl" src="/assets/lms/icons/comment.svg">
|
<img class="icon icon-xl" src="/assets/lms/icons/comment.svg">
|
||||||
@@ -27,15 +27,38 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{%- block script %}
|
{% macro ClassTabs(past_classes, upcoming_classes) %}
|
||||||
{{ super() }}
|
<article>
|
||||||
{{ include_script('controls.bundle.js') }}
|
<ul class="nav lms-nav" id="courses-tab">
|
||||||
{% if is_moderator %}
|
|
||||||
<script>
|
<li class="nav-item">
|
||||||
let class_info = null;
|
<a class="nav-link active" data-toggle="tab" href="#upcoming">
|
||||||
</script>
|
{{ _("Upcoming") }} ({{ upcoming_classes | length }})
|
||||||
{% endif %}
|
</a>
|
||||||
{% endblock %}
|
</li>
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" data-toggle="tab" href="#past">
|
||||||
|
{{ _("Past Classes") }} ({{ past_classes | length }})
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="border-bottom mb-4"></div>
|
||||||
|
|
||||||
|
<div class="tab-content">
|
||||||
|
<div class="tab-pane active" id="upcoming" role="tabpanel" aria-labelledby="upcoming">
|
||||||
|
{{ ClassCards(upcoming_classes) }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tab-pane" id="past" role="tabpanel" aria-labelledby="past">
|
||||||
|
{{ ClassCards(past_classes) }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro ClassCards(classes) %}
|
{% macro ClassCards(classes) %}
|
||||||
<div class="lms-card-parent">
|
<div class="lms-card-parent">
|
||||||
@@ -79,3 +102,13 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
{%- block script %}
|
||||||
|
{{ super() }}
|
||||||
|
{{ include_script('controls.bundle.js') }}
|
||||||
|
{% if is_moderator %}
|
||||||
|
<script>
|
||||||
|
let class_info = null;
|
||||||
|
</script>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
@@ -6,8 +6,15 @@ from lms.lms.utils import has_course_moderator_role
|
|||||||
def get_context(context):
|
def get_context(context):
|
||||||
context.no_cache = 1
|
context.no_cache = 1
|
||||||
context.is_moderator = has_course_moderator_role()
|
context.is_moderator = has_course_moderator_role()
|
||||||
context.classes = frappe.get_all(
|
classes = frappe.get_all(
|
||||||
"LMS Class",
|
"LMS Class",
|
||||||
{"end_date": [">=", getdate()]},
|
fields=["name", "title", "start_date", "end_date"],
|
||||||
["name", "title", "start_date", "end_date"],
|
|
||||||
)
|
)
|
||||||
|
past_classes, upcoming_classes = [], []
|
||||||
|
for class_ in classes:
|
||||||
|
if getdate(class_.end_date) < getdate():
|
||||||
|
past_classes.append(class_)
|
||||||
|
else:
|
||||||
|
upcoming_classes.append(class_)
|
||||||
|
context.past_classes = past_classes
|
||||||
|
context.upcoming_classes = upcoming_classes
|
||||||
|
|||||||
Reference in New Issue
Block a user