feat: course creation from ui

This commit is contained in:
Jannat Patel
2022-03-09 12:29:03 +05:30
parent 913e87c4f5
commit 8f9cd72975
16 changed files with 300 additions and 16 deletions

View File

@@ -59,7 +59,7 @@
"link_fieldname": "chapter"
}
],
"modified": "2021-09-29 15:33:44.611229",
"modified": "2022-03-08 15:21:10.389729",
"modified_by": "Administrator",
"module": "LMS",
"name": "Course Chapter",
@@ -77,11 +77,25 @@
"role": "System Manager",
"share": 1,
"write": 1
},
{
"create": 1,
"email": 1,
"export": 1,
"if_owner": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "All",
"select": 1,
"share": 1,
"write": 1
}
],
"search_fields": "title",
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"title_field": "title",
"track_changes": 1
}
}

View File

@@ -1,6 +1,6 @@
{
"actions": [],
"allow_import": 1,
"allow_events_in_timeline": 1,
"allow_rename": 1,
"autoname": "format:{####} {title}",
"creation": "2021-05-03 06:21:12.995984",
@@ -73,7 +73,7 @@
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-10-11 15:07:38.134808",
"modified": "2022-03-08 17:56:50.504143",
"modified_by": "Administrator",
"module": "LMS",
"name": "Course Lesson",
@@ -89,11 +89,26 @@
"read": 1,
"report": 1,
"role": "System Manager",
"select": 1,
"share": 1,
"write": 1
},
{
"create": 1,
"email": 1,
"export": 1,
"if_owner": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "All",
"select": 1,
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
}

View File

@@ -6,7 +6,7 @@ from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
from ...md import find_macros
from school.lms.utils import get_course_progress
from school.lms.utils import get_course_progress, get_lesson_url
class CourseLesson(Document):
def validate(self):
@@ -108,3 +108,13 @@ def save_progress(lesson, course, status):
progress = get_course_progress(course)
frappe.db.set_value("LMS Batch Membership", membership, "progress", progress)
return progress
@frappe.whitelist()
def get_lesson_info(lesson_name):
chapter = frappe.db.get_value("Course Lesson", lesson_name, "chapter")
course = frappe.db.get_value("Course Chapter", chapter, "course")
lesson_idx = frappe.db.get_value("Lesson Reference", {"lesson": lesson_name}, ["idx"])
chapter_idx = frappe.db.get_value("Chapter Reference", {"chapter": chapter}, ["idx"])
return get_lesson_url(course, f"{chapter_idx}.{lesson_idx}")

View File

@@ -7,7 +7,6 @@
"label": "Reindex Exercises"
}
],
"allow_guest_to_view": 1,
"allow_import": 1,
"allow_rename": 1,
"creation": "2022-02-22 15:28:26.091549",
@@ -150,7 +149,6 @@
"options": "Related Courses"
}
],
"index_web_pages_for_search": 1,
"is_published_field": "is_published",
"links": [
{
@@ -174,7 +172,7 @@
"link_fieldname": "course"
}
],
"modified": "2022-03-07 14:47:51.745509",
"modified": "2022-03-08 15:20:58.501082",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Course",
@@ -189,6 +187,7 @@
"read": 1,
"report": 1,
"role": "System Manager",
"select": 1,
"share": 1,
"write": 1
},

View File

View File

@@ -0,0 +1,3 @@
frappe.ready(function() {
// bind events here
})

View File

@@ -0,0 +1,89 @@
{
"accept_payment": 0,
"allow_comments": 0,
"allow_delete": 0,
"allow_edit": 1,
"allow_incomplete": 0,
"allow_multiple": 1,
"allow_print": 0,
"amount": 0.0,
"amount_based_on_field": 0,
"apply_document_permissions": 0,
"button_label": "Save",
"creation": "2022-03-07 18:41:07.058806",
"doc_type": "Course Chapter",
"docstatus": 0,
"doctype": "Web Form",
"idx": 0,
"is_multi_step_form": 0,
"is_standard": 1,
"login_required": 1,
"max_attachment_size": 0,
"modified": "2022-03-07 18:41:07.058806",
"modified_by": "Administrator",
"module": "LMS",
"name": "chapter",
"owner": "Administrator",
"payment_button_label": "Buy Now",
"published": 1,
"route": "chapter",
"route_to_success_link": 0,
"show_attachments": 0,
"show_in_grid": 0,
"show_sidebar": 0,
"sidebar_items": [],
"success_url": "/chapter",
"title": "Chapter",
"web_form_fields": [
{
"allow_read_on_all_link_options": 0,
"fieldname": "course",
"fieldtype": "Link",
"hidden": 0,
"label": "Course",
"max_length": 0,
"max_value": 0,
"options": "LMS Course",
"read_only": 0,
"reqd": 1,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "title",
"fieldtype": "Data",
"hidden": 0,
"label": "Title",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 1,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "description",
"fieldtype": "Small Text",
"hidden": 0,
"label": "Description",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "lessons",
"fieldtype": "Table",
"hidden": 0,
"label": "Lessons",
"max_length": 0,
"max_value": 0,
"options": "Lesson Reference",
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
}
]
}

View File

@@ -0,0 +1,5 @@
import frappe
def get_context(context):
# do your magic here
pass

View File

@@ -1,3 +1,7 @@
frappe.ready(function() {
// bind events here
})
frappe.web_form.after_save = () => {
setTimeout(() => {
window.location.href = `/courses/${frappe.web_form.doc.name}`;
})
}
});

View File

@@ -20,7 +20,7 @@
"is_standard": 1,
"login_required": 1,
"max_attachment_size": 0,
"modified": "2022-03-07 14:48:04.889844",
"modified": "2022-03-09 10:10:30.069458",
"modified_by": "Administrator",
"module": "LMS",
"name": "course",
@@ -48,6 +48,29 @@
"reqd": 1,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "tags",
"fieldtype": "Data",
"hidden": 0,
"label": "Tags",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "",
"fieldtype": "Column Break",
"hidden": 0,
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "video_link",
@@ -74,10 +97,9 @@
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "tags",
"fieldtype": "Data",
"fieldname": "",
"fieldtype": "Section Break",
"hidden": 0,
"label": "Tags",
"max_length": 0,
"max_value": 0,
"read_only": 0,

View File

View File

@@ -0,0 +1,17 @@
frappe.ready(function() {
frappe.web_form.after_save = () => {
setTimeout(() => {
frappe.call({
method: "school.lms.doctype.course_lesson.course_lesson.get_lesson_info",
args: {
"lesson_name": frappe.web_form.doc.name
},
callback: (data) => {
window.location.href = data.message;
}
});
});
};
});

View File

@@ -0,0 +1,91 @@
{
"accept_payment": 0,
"allow_comments": 0,
"allow_delete": 0,
"allow_edit": 1,
"allow_incomplete": 0,
"allow_multiple": 1,
"allow_print": 0,
"amount": 0.0,
"amount_based_on_field": 0,
"apply_document_permissions": 1,
"button_label": "Save",
"creation": "2022-03-07 18:41:42.549831",
"custom_css": "",
"doc_type": "Course Lesson",
"docstatus": 0,
"doctype": "Web Form",
"idx": 0,
"introduction_text": "<div class=\"ql-editor read-mode\"><p><br></p><p><br></p><p>Create lessons for your course. You can add some additional content to the lesson using a special syntax. The table below mentions all types of dynamic content that you can add to the lessons and the syntax for the same.</p><p><br></p><table class=\"table table-bordered\"><tbody><tr><td data-row=\"row-wxk1\"><strong>Content Type</strong></td><td data-row=\"row-wxk1\"><strong>Syntax</strong></td></tr><tr><td data-row=\"row-lawj\">Video</td><td data-row=\"row-lawj\">{{ Video(\"url_of_source\") }}</td></tr><tr><td data-row=\"insert-table\">YouTube Video</td><td data-row=\"insert-table\">{{ YouTubeVideo(\"unique_embed_id\") }}</td></tr><tr><td data-row=\"insert-row-below\">Exercise</td><td data-row=\"insert-row-below\">{{ Exercise(\"exercise_name\") }}</td></tr><tr><td data-row=\"row-3b6n\">Quiz</td><td data-row=\"row-3b6n\">{{ Quiz(\"lms_quiz_name\") }}</td></tr><tr><td data-row=\"row-r57s\">Assignment</td><td data-row=\"row-r57s\">{{ Assignment(\"id-filetype\") }}</td></tr></tbody></table></div>",
"is_multi_step_form": 0,
"is_standard": 1,
"login_required": 1,
"max_attachment_size": 0,
"modified": "2022-03-09 09:55:58.406164",
"modified_by": "Administrator",
"module": "LMS",
"name": "lesson",
"owner": "Administrator",
"payment_button_label": "Buy Now",
"published": 1,
"route": "lesson",
"route_to_success_link": 0,
"show_attachments": 0,
"show_in_grid": 0,
"show_sidebar": 0,
"sidebar_items": [],
"success_url": "/lesson",
"title": "Lesson",
"web_form_fields": [
{
"allow_read_on_all_link_options": 1,
"fieldname": "chapter",
"fieldtype": "Link",
"hidden": 0,
"label": "Course Chapter",
"max_length": 0,
"max_value": 0,
"options": "Course Chapter",
"read_only": 0,
"reqd": 1,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "title",
"fieldtype": "Data",
"hidden": 0,
"label": "Title",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 1,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"default": "0",
"fieldname": "include_in_preview",
"fieldtype": "Check",
"hidden": 0,
"label": "Include In Preview",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "body",
"fieldtype": "Data",
"hidden": 0,
"label": "Body",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 1,
"show_in_filter": 0
}
]
}

View File

@@ -0,0 +1,5 @@
import frappe
def get_context(context):
# do your magic here
pass

View File

@@ -42,10 +42,13 @@
{% if membership or is_instructor %} eligible-for-submission {% endif %}" data-lesson="{{ lesson.name }}"
data-course="{{ course.name }}">{{ lesson.title }}</div>
<span class="lesson-progress {{hide if get_progress(course.name, lesson.name) != 'Complete' else ''}}">COMPLETED</span>
{% if is_instructor %}
<a class="button is-default button-links ml-auto" href="/lesson?name={{ lesson.name }}"> {{ _("Edit") }} </a>
{% endif %}
</div>
<div class="d-flex align-items-center">
{% set instructors = instructors %}
{% set ins_len = instructors | length %}
{% for instructor in instructors %}
{% if ins_len > 1 and loop.index == 1 %}

View File

@@ -1,9 +1,11 @@
{% extends "templates/base.html" %}
{% block title %}{{ course.title }}
{% endblock %}
{% block head_include %}
<link rel="stylesheet" href="/assets/frappe/css/font-awesome.css">
{% endblock %}
{% block content %}
<div class="common-page-style pt-0">
<div class="course-home-top-container">
@@ -26,6 +28,11 @@
style=" {% if course.image %} background-position: center; background-size: cover; background-image: url({{ course.image }});
{% else %} background-color: var(--gray-200) {% endif %}">
<div class="container pt-10 pb-10">
{% if is_instructor(course.name) %}
<a class="button is-default button-links pull-right" href="/lesson?new=1"> {{ _("New Lesson") }} </a>
<a class="button is-default button-links pull-right mr-2" href="/chapter?new=1"> {{ _("New Chapter") }} </a>
<a class="button is-default button-links pull-right mr-2" href="/course?name={{ course.name }}"> {{ _("Edit") }} </a>
{% endif %}
{{ BreadCrumb(course) }}
{{ CourseCardWide(course) }}
</div>