feat: my class tab
This commit is contained in:
@@ -24,26 +24,39 @@ class LMSAssignmentSubmission(Document):
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def upload_assignment(assignment_attachment, assignment, lesson=None):
|
||||
def upload_assignment(
|
||||
assignment_attachment,
|
||||
assignment,
|
||||
lesson=None,
|
||||
status="Not Graded",
|
||||
comments=None,
|
||||
submission=None,
|
||||
):
|
||||
if frappe.session.user == "Guest":
|
||||
return
|
||||
|
||||
args = {
|
||||
"doctype": "LMS Assignment Submission",
|
||||
"member": frappe.session.user,
|
||||
"assignment": assignment,
|
||||
}
|
||||
if frappe.db.exists(args):
|
||||
del args["doctype"]
|
||||
frappe.db.set_value(
|
||||
"LMS Assignment Submission", args, "assignment_attachment", assignment_attachment
|
||||
)
|
||||
return frappe.db.get_value("LMS Assignment Submission", args, "name")
|
||||
if submission:
|
||||
doc = frappe.get_doc("LMS Assignment Submission", submission)
|
||||
else:
|
||||
args.update({"assignment_attachment": assignment_attachment})
|
||||
doc = frappe.get_doc(args)
|
||||
doc.save(ignore_permissions=True)
|
||||
return doc.name
|
||||
doc = frappe.get_doc(
|
||||
{
|
||||
"doctype": "LMS Assignment Submission",
|
||||
"assignment": assignment,
|
||||
"lesson": lesson,
|
||||
"member": frappe.session.user,
|
||||
}
|
||||
)
|
||||
print(doc.assignment)
|
||||
print(comments)
|
||||
doc.update(
|
||||
{
|
||||
"assignment_attachment": assignment_attachment,
|
||||
"status": status,
|
||||
"comments": comments,
|
||||
}
|
||||
)
|
||||
doc.save(ignore_permissions=True)
|
||||
return doc.name
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
|
||||
@@ -1916,6 +1916,10 @@ li {
|
||||
justify-content: flex-end !important;
|
||||
}
|
||||
|
||||
.modal-footer .btn-primary {
|
||||
margin-left: 0.5rem
|
||||
}
|
||||
|
||||
.modal-header .modal-title {
|
||||
color: var(--gray-900);
|
||||
line-height: 1.5rem;
|
||||
|
||||
@@ -16,25 +16,32 @@
|
||||
<header class="sticky mb-5">
|
||||
<div class="container form-width">
|
||||
<div class="edit-header">
|
||||
<div class="vertically-center">
|
||||
<div class="page-title">
|
||||
{{ assignment.title }}
|
||||
<div>
|
||||
<div class="vertically-center">
|
||||
<div class="page-title">
|
||||
{{ assignment.title }}
|
||||
</div>
|
||||
{% if submission.status %}
|
||||
{% set color = "green" if submission.status == "Pass" else "red" if submission.status == "Fail" else "orange" %}
|
||||
<div class="indicator-pill {{ color }} ml-2">
|
||||
{{ submission.status }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if submission.status %}
|
||||
{% set color = "green" if submission.status == "Pass" else "red" if submission.status == "Fail" else "orange" %}
|
||||
<div class="indicator-pill {{ color }} ml-2">
|
||||
{{ submission.status }}
|
||||
<div class="vertically-center small">
|
||||
<a class="dark-links" href="/classes">
|
||||
{{ _("All Classes") }}
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if submission.status == "Not Graded" %}
|
||||
|
||||
<div class="align-self-center">
|
||||
<button class="btn btn-primary btn-sm btn-save-assignment" {% if assignment.name %} data-assignment="{{ assignment.name }}" {% endif %}>
|
||||
<button class="btn btn-primary btn-sm btn-save-assignment" {% if assignment.name %} data-assignment="{{ assignment.name }}" {% endif %}
|
||||
{% if submission.name %} data-submission="{{ submission.name }}" {% endif %}>
|
||||
{{ _("Save") }}
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
@@ -42,17 +49,19 @@
|
||||
|
||||
{% macro SubmissionForm(assignment) %}
|
||||
<article class="field-parent">
|
||||
{% if submission.name and is_moderator %}
|
||||
<div class="field-group">
|
||||
<div class="field-label">
|
||||
{{ _("Student") }}
|
||||
{{ _("Student Name") }}
|
||||
</div>
|
||||
{{ submission.member_name }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="field-group">
|
||||
<!-- <div class="field-label">
|
||||
<div class="field-label">
|
||||
{{ _("Question")}}
|
||||
</div> -->
|
||||
</div>
|
||||
{{ assignment.question }}
|
||||
</div>
|
||||
|
||||
@@ -64,18 +73,61 @@
|
||||
{{ _("Upload assignment as {0}").format(assignment.type) }}
|
||||
</div>
|
||||
|
||||
<div class="file-source-preview">
|
||||
{% if submission.status == "Not Graded" and submission.member == frappe.session.user %}
|
||||
<span class="btn btn-default btn-sm btn-close">
|
||||
{{ _("Clear") }}
|
||||
|
||||
<div class="btn btn-default btn-sm btn-upload mt-2 {% if submission.assignment_attachment %} hide {% endif %}" data-type="{{ assignment.type }}">
|
||||
{{ _("Browse").format(assignment.type) }}
|
||||
</div>
|
||||
<div class="field-input flex justify-between align-center {% if not submission.assignment_attachment %} hide {% endif %}" id="assignment-preview">
|
||||
<a class="clickable" {% if submission.assignment_attachment %} href="{{ submission.assignment_attachment }}" {% endif %}>
|
||||
{% if submission.assignment_attachment %} {{ submission.assignment_attachment }} {% endif %}
|
||||
</a>
|
||||
<span class="btn btn-default btn-sm btn-close {% if not submission %} hide {% endif %}">
|
||||
{{ _("Clear") }}
|
||||
</span>
|
||||
{% endif %}
|
||||
<div class="btn-upload clickable {% if submission.assignment_attachment %} hide {% endif %}" data-type="{{ assignment.type }}">
|
||||
{{ _("Browse").format(assignment.type) }}
|
||||
</div>
|
||||
<iframe class="image-preview {% if not submission.assignment_attachment %} hide {% endif %}" {% if submission.assignment_attachment %} src="{{ submission.assignment_attachment }}" {% endif %}></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if is_moderator %}
|
||||
<div class="field-group">
|
||||
<div class="field-label">
|
||||
{{ _("Status") }}
|
||||
</div>
|
||||
<div class="field-input flex align-center">
|
||||
<select class="form-control" id="status">
|
||||
{% set statuses = ["Not Graded", "Pass", "Fail"] %}
|
||||
{% for status in statuses %}
|
||||
<option value="{{ status }}" {% if submission.status == status %} selected {% endif %}>
|
||||
{{ status }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div class="select-icon">
|
||||
<svg class="icon icon-sm">
|
||||
<use class="" href="#icon-select"></use>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field-group">
|
||||
<div class="field-label">
|
||||
{{ _("Comments by Mentor") }}
|
||||
</div>
|
||||
<textarea id="comments" type="text" class="field-input" height="300px"
|
||||
>{% if submission.comments %}{{ submission.comments }}{% endif %}</textarea>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if submission and submission.member == frappe.session.user and submission.comments %}
|
||||
<div class="field-group">
|
||||
<div class="field-label">
|
||||
{{ _("Comments by Mentor") }}
|
||||
</div>
|
||||
<div>
|
||||
{{ submission.comments }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</article>
|
||||
{% endmacro %}
|
||||
@@ -15,10 +15,15 @@ frappe.ready(() => {
|
||||
const upload_file = (e) => {
|
||||
let type = $(e.currentTarget).data("type");
|
||||
let mapper = {
|
||||
Image: "image/*",
|
||||
Document:
|
||||
".doc,.docx,.xml,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
PDF: ".pdf",
|
||||
Image: ["image/*"],
|
||||
Document: [
|
||||
".doc",
|
||||
".docx",
|
||||
".xml",
|
||||
"application/msword",
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
],
|
||||
PDF: [".pdf"],
|
||||
};
|
||||
|
||||
new frappe.ui.FileUploader({
|
||||
@@ -26,20 +31,23 @@ const upload_file = (e) => {
|
||||
folder: "Home/Attachments",
|
||||
make_attachments_public: true,
|
||||
restrictions: {
|
||||
allowed_file_types: [mapper[type]],
|
||||
allowed_file_types: mapper[type],
|
||||
},
|
||||
on_success: (file_doc) => {
|
||||
$(e.currentTarget).addClass("hide");
|
||||
$(".file-source-preview .btn-close").removeClass("hide");
|
||||
$(".file-source-preview iframe")
|
||||
.attr("src", file_doc.file_url)
|
||||
.removeClass("hide");
|
||||
$("#assignment-preview").removeClass("hide");
|
||||
$("#assignment-preview .btn-close").removeClass("hide");
|
||||
$("#assignment-preview a").attr(
|
||||
"href",
|
||||
encodeURI(file_doc.file_url)
|
||||
);
|
||||
$("#assignment-preview a").text(file_doc.file_url);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const save_assignment = (e) => {
|
||||
let file = $(".image-preview").attr("src");
|
||||
let file = $("#assignment-preview a").attr("href");
|
||||
if (!file) {
|
||||
frappe.throw({
|
||||
title: __("No File"),
|
||||
@@ -51,7 +59,10 @@ const save_assignment = (e) => {
|
||||
method: "lms.lms.doctype.lms_assignment_submission.lms_assignment_submission.upload_assignment",
|
||||
args: {
|
||||
assignment: $(e.currentTarget).data("assignment"),
|
||||
submission: $(e.currentTarget).data("submission") || "",
|
||||
assignment_attachment: file,
|
||||
status: $("#status").val(),
|
||||
comments: $("#comments").val(),
|
||||
},
|
||||
callback: (data) => {
|
||||
frappe.show_alert({
|
||||
@@ -68,7 +79,8 @@ const save_assignment = (e) => {
|
||||
};
|
||||
|
||||
const clear_preview = (e) => {
|
||||
$(".file-source-preview .btn-upload").removeClass("hide");
|
||||
$(".file-source-preview iframe").attr("src", "").addClass("hide");
|
||||
$(".file-source-preview .btn-close").addClass("hide");
|
||||
$(".btn-upload").removeClass("hide");
|
||||
$("#assignment-preview").addClass("hide");
|
||||
$("#assignment-preview a").attr("href", "");
|
||||
$("#assignment-preview .btn-close").addClass("hide");
|
||||
};
|
||||
|
||||
@@ -25,5 +25,5 @@ def get_context(context):
|
||||
if not context.is_moderator and frappe.session.user != context.submission.member:
|
||||
raise frappe.PermissionError(_("You don't have permission to access this page."))
|
||||
|
||||
if not context.assignment or not context.submission:
|
||||
raise frappe.PermissionError(_("Invalid Submission URL"))
|
||||
if not context.assignment or not context.submission:
|
||||
raise frappe.PermissionError(_("Invalid Submission URL"))
|
||||
|
||||
@@ -263,7 +263,7 @@
|
||||
{{ _("To create a new assignment for this class, click on the create assignment button. Once you have created the new assignment you can come back to the class and add the assignment from here.") }}
|
||||
</p>
|
||||
<div>
|
||||
<a class="btn btn-default btn-sm" href="/assignments/new-assignment" target="_blank">
|
||||
<a class="btn btn-default btn-sm" href="/assignments/new-assignment">
|
||||
{{ _("Create Assignment") }}
|
||||
</a>
|
||||
</div>
|
||||
@@ -322,7 +322,7 @@
|
||||
{% if assessments | length %}
|
||||
<div>
|
||||
<div class="list-row level level-left small">
|
||||
<div class="w-50">
|
||||
<div class="w-25">
|
||||
{{ _("Title") }}
|
||||
</div>
|
||||
<div class="">
|
||||
@@ -331,7 +331,7 @@
|
||||
</div>
|
||||
{% for assessment in assessments %}
|
||||
<div class="list-row level level-left">
|
||||
<div class="w-50">
|
||||
<div class="w-25">
|
||||
<a class="clickable" href="{{ assessment.edit_url }}">
|
||||
{{ assessment.title }}
|
||||
</a>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<div class="container">
|
||||
{{ Header() }}
|
||||
{% if past_classes | length or upcoming_classes | length %}
|
||||
{{ ClassTabs(past_classes, upcoming_classes) }}
|
||||
{{ ClassTabs(past_classes, upcoming_classes, my_classes) }}
|
||||
{% else %}
|
||||
{{ EmptyState() }}
|
||||
{% endif %}
|
||||
@@ -27,7 +27,7 @@
|
||||
</header>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro ClassTabs(past_classes, upcoming_classes) %}
|
||||
{% macro ClassTabs(past_classes, upcoming_classes, my_classes) %}
|
||||
<article>
|
||||
<ul class="nav lms-nav" id="courses-tab">
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{% if is_moderator %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" href="#past">
|
||||
{{ _("Past Classes") }}
|
||||
@@ -48,6 +49,18 @@
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% if frappe.session.user != "Guest" %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" href="#my-class">
|
||||
{{ _("My Classes") }}
|
||||
<span class="course-list-count">
|
||||
{{ my_classes | length }}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
</ul>
|
||||
|
||||
@@ -58,9 +71,17 @@
|
||||
{{ ClassCards(upcoming_classes) }}
|
||||
</div>
|
||||
|
||||
{% if is_moderator %}
|
||||
<div class="tab-pane" id="past" role="tabpanel" aria-labelledby="past">
|
||||
{{ ClassCards(past_classes) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if frappe.session.user != "Guest" %}
|
||||
<div class="tab-pane" id="my-class" role="tabpanel" aria-labelledby="my-classes">
|
||||
{{ ClassCards(my_classes) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</article>
|
||||
|
||||
@@ -20,5 +20,24 @@ def get_context(context):
|
||||
upcoming_classes.append(class_)
|
||||
|
||||
context.past_classes = sorted(past_classes, key=lambda d: d.start_date)
|
||||
|
||||
context.upcoming_classes = sorted(upcoming_classes, key=lambda d: d.start_date)
|
||||
|
||||
if frappe.session.user != "Guest":
|
||||
my_classes_info = []
|
||||
my_classes = frappe.get_all(
|
||||
"Class Student", {"student": frappe.session.user}, pluck="parent"
|
||||
)
|
||||
|
||||
for class_ in my_classes:
|
||||
my_classes_info.append(
|
||||
frappe.db.get_value(
|
||||
"LMS Class",
|
||||
class_,
|
||||
["name", "title", "start_date", "end_date", "paid_class", "seat_count"],
|
||||
as_dict=True,
|
||||
)
|
||||
)
|
||||
|
||||
context.my_classes = my_classes_info
|
||||
|
||||
print(context.my_classes)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<div class="common-page-style">
|
||||
{{ Header() }}
|
||||
<div class="container form-width">
|
||||
{{ Progress() }}
|
||||
{{ Progress(class_info, student) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -50,7 +50,7 @@
|
||||
<div>
|
||||
{% for assessment in assessments %}
|
||||
<div class="list-row level">
|
||||
<a {% if assessment.submission %} class="clickable" href="{{ assessment.url }}" {% endif %}>
|
||||
<a {% if is_moderator and assessment.submission or frappe.session.user == student.name %} class="clickable" href="{{ assessment.url }}" {% endif %}>
|
||||
{{ assessment.title }}
|
||||
</a>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user