test: fixed course creation test
This commit is contained in:
@@ -1,14 +1,6 @@
|
||||
frappe.ready(() => {
|
||||
hide_wrapped_mentor_cards();
|
||||
|
||||
$("#cancel-request").click((e) => {
|
||||
cancel_mentor_request(e);
|
||||
});
|
||||
|
||||
$(".view-all-mentors").click((e) => {
|
||||
view_all_mentors(e);
|
||||
});
|
||||
|
||||
$(".review-link").click((e) => {
|
||||
show_review_dialog(e);
|
||||
});
|
||||
@@ -48,30 +40,6 @@ frappe.ready(() => {
|
||||
$(document).on("click", ".slot", (e) => {
|
||||
select_slot(e);
|
||||
});
|
||||
|
||||
$(".btn-attach").click((e) => {
|
||||
show_upload_modal(e);
|
||||
});
|
||||
|
||||
$(".btn-clear").click((e) => {
|
||||
clear_image(e);
|
||||
});
|
||||
|
||||
$(".btn-tag").click((e) => {
|
||||
add_tag(e);
|
||||
});
|
||||
|
||||
$(".btn-save-course").click((e) => {
|
||||
save_course(e);
|
||||
});
|
||||
|
||||
$(".btn-delete-tag").click((e) => {
|
||||
remove_tag(e);
|
||||
});
|
||||
|
||||
if ($("#description").length) {
|
||||
make_editor();
|
||||
}
|
||||
});
|
||||
|
||||
const hide_wrapped_mentor_cards = () => {
|
||||
@@ -92,42 +60,6 @@ const hide_wrapped_mentor_cards = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const cancel_mentor_request = (e) => {
|
||||
e.preventDefault();
|
||||
frappe.call({
|
||||
method: "lms.lms.doctype.lms_mentor_request.lms_mentor_request.cancel_request",
|
||||
args: {
|
||||
course: decodeURIComponent($(e.currentTarget).attr("data-course")),
|
||||
},
|
||||
callback: (data) => {
|
||||
if (data.message == "OK") {
|
||||
$("#mentor-request").removeClass("hide");
|
||||
$("#already-applied").addClass("hide");
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const view_all_mentors = (e) => {
|
||||
$(".wrapped").each((i, element) => {
|
||||
$(element).slideToggle("slow");
|
||||
});
|
||||
var text_element = $(
|
||||
".view-all-mentors .course-instructor .all-mentors-text"
|
||||
);
|
||||
var text =
|
||||
text_element.text() == "View all mentors"
|
||||
? "View less"
|
||||
: "View all mentors";
|
||||
text_element.text(text);
|
||||
|
||||
if ($(".mentor-icon").css("transform") == "none") {
|
||||
$(".mentor-icon").css("transform", "rotate(180deg)");
|
||||
} else {
|
||||
$(".mentor-icon").css("transform", "");
|
||||
}
|
||||
};
|
||||
|
||||
const show_review_dialog = (e) => {
|
||||
e.preventDefault();
|
||||
$("#review-modal").modal("show");
|
||||
@@ -326,84 +258,3 @@ const close_slot_modal = (e) => {
|
||||
$("#slot-date").val("");
|
||||
$(".slot-label").addClass("hide");
|
||||
};
|
||||
|
||||
const show_upload_modal = () => {
|
||||
new frappe.ui.FileUploader({
|
||||
folder: "Home/Attachments",
|
||||
restrictions: {
|
||||
allowed_file_types: ["image/*"],
|
||||
},
|
||||
on_success: (file_doc) => {
|
||||
$(".course-image-attachment").removeClass("hide");
|
||||
$(".course-image-attachment a")
|
||||
.attr("href", file_doc.file_url)
|
||||
.text(file_doc.file_url);
|
||||
$(".btn-attach").addClass("hide");
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const clear_image = () => {
|
||||
$(".course-image-attachment").addClass("hide");
|
||||
$(".course-image-attachment a").removeAttr("href");
|
||||
$(".btn-attach").removeClass("hide");
|
||||
};
|
||||
|
||||
const add_tag = (e) => {
|
||||
$(`<div class="course-card-pills" contenteditable="true"
|
||||
data-placeholder="${__("Tag")}"></div>`).insertBefore(`.btn-tag`);
|
||||
};
|
||||
|
||||
const save_course = (e) => {
|
||||
let tags = $(".course-card-pills")
|
||||
.map((i, el) => $(el).text().trim())
|
||||
.get();
|
||||
tags = tags.filter((word) => word.trim().length > 0);
|
||||
|
||||
frappe.call({
|
||||
method: "lms.lms.doctype.lms_course.lms_course.save_course",
|
||||
args: {
|
||||
tags: tags.join(", "),
|
||||
title: $("#title").text(),
|
||||
short_introduction: $("#intro").text(),
|
||||
video_link: $("#video-link").text(),
|
||||
image: $("#image").attr("href"),
|
||||
description: this.code_field_group.fields_dict["code_md"].value,
|
||||
course: $("#title").data("course")
|
||||
? $("#title").data("course")
|
||||
: "",
|
||||
published: $("#published").prop("checked") ? 1 : 0,
|
||||
upcoming: $("#upcoming").prop("checked") ? 1 : 0,
|
||||
},
|
||||
callback: (data) => {
|
||||
frappe.show_alert({
|
||||
message: __("Saved"),
|
||||
indicator: "green",
|
||||
});
|
||||
setTimeout(() => {
|
||||
window.location.href = `/courses/${data.message}?edit=1`;
|
||||
}, 1000);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const remove_tag = (e) => {
|
||||
$(e.currentTarget).closest(".course-card-pills").remove();
|
||||
};
|
||||
|
||||
const make_editor = () => {
|
||||
this.code_field_group = new frappe.ui.FieldGroup({
|
||||
fields: [
|
||||
{
|
||||
fieldname: "code_md",
|
||||
fieldtype: "Text Editor",
|
||||
default: $(".description-data").html(),
|
||||
},
|
||||
],
|
||||
body: $("#description").get(0),
|
||||
});
|
||||
this.code_field_group.make();
|
||||
$("#description .form-section:last").removeClass("empty-section");
|
||||
$("#description .frappe-control").removeClass("hide-control");
|
||||
$("#description .form-column").addClass("p-0");
|
||||
};
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
<div class="field-parent">
|
||||
<div class="field-group">
|
||||
<div>
|
||||
<div class="field-label">
|
||||
<div class="field-label reqd">
|
||||
{{ _("Title") }}
|
||||
</div>
|
||||
<div class="field-description">
|
||||
@@ -60,21 +60,7 @@
|
||||
|
||||
<div class="field-group">
|
||||
<div>
|
||||
<div class="field-label">
|
||||
{{ _("Preview Video") }}
|
||||
</div>
|
||||
<div class="field-description">
|
||||
{{ _("A feature video that provides a preview of the course") }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="">
|
||||
<input id="video-link" type="text" class="field-input" {% if course.video_link %} value="{{ course.video_link }}" {% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field-group">
|
||||
<div>
|
||||
<div class="field-label">
|
||||
<div class="field-label reqd">
|
||||
{{ _("Short Introduction") }}
|
||||
</div>
|
||||
<div class="field-description">
|
||||
@@ -86,6 +72,37 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field-group">
|
||||
<div>
|
||||
<div class="field-label reqd">
|
||||
{{ _("Course Description") }}
|
||||
</div>
|
||||
<div class="field-description">
|
||||
{{ _("Add a detailed description") }}
|
||||
</div>
|
||||
</div>
|
||||
<div id="description" class=""></div>
|
||||
{% if course.description %}
|
||||
<div id="description-data" class="hide">
|
||||
{{ course.description }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="field-group">
|
||||
<div>
|
||||
<div class="field-label">
|
||||
{{ _("Preview Video ID") }}
|
||||
</div>
|
||||
<div class="field-description">
|
||||
{{ _("Enter the Preview Video ID. The ID is the part of the URL after <code>watch?v=</code>. For example, if the URL is <code>https://www.youtube.com/watch?v=QH2-TGUlwu4</code>, the ID is <code>QH2-TGUlwu4</code>") }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="">
|
||||
<input id="video-link" type="text" class="field-input" {% if course.video_link %} value="{{ course.video_link }}" {% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field-group">
|
||||
<div>
|
||||
<div class="field-label">
|
||||
@@ -110,12 +127,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field-group">
|
||||
<label for="published" class="mb-0">
|
||||
<div class="field-group vertically-center">
|
||||
<label for="published" class="vertically-center mb-0">
|
||||
<input type="checkbox" id="published" {% if course.published %} checked {% endif %}>
|
||||
{{ _("Published") }}
|
||||
</label>
|
||||
<label for="upcoming" class="mb-0 ml-20">
|
||||
<label for="upcoming" class="vertically-center mb-0 ml-20">
|
||||
<input type="checkbox" id="upcoming" {% if course.upcoming %} checked {% endif %}>
|
||||
{{ _("Upcoming") }}
|
||||
</label>
|
||||
@@ -138,23 +155,6 @@
|
||||
<img {% if course.image %} class="image-preview" src="{{ course.image }}" {% endif %}>
|
||||
</div>
|
||||
|
||||
<div class="field-group">
|
||||
<div>
|
||||
<div class="field-label">
|
||||
{{ _("Course Description") }}
|
||||
</div>
|
||||
<div class="field-description">
|
||||
{{ _("Add a detailed description") }}
|
||||
</div>
|
||||
</div>
|
||||
<div id="description" class=""></div>
|
||||
{% if course.description %}
|
||||
<div id="description-data" class="hide">
|
||||
{{ course.description }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="field-group">
|
||||
<div class="field-label">
|
||||
{{ _("Instructor") }}
|
||||
|
||||
@@ -20,6 +20,12 @@ frappe.ready(() => {
|
||||
make_editor();
|
||||
}
|
||||
|
||||
$(".field-input").focusout((e) => {
|
||||
if ($(e.currentTarget).siblings(".error-message")) {
|
||||
$(e.currentTarget).siblings(".error-message").remove();
|
||||
}
|
||||
});
|
||||
|
||||
$("#tags-input").focus((e) => {
|
||||
$(e.target).keypress((e) => {
|
||||
if (e.which == 13) {
|
||||
@@ -50,6 +56,7 @@ const create_tag = (e) => {
|
||||
};
|
||||
|
||||
const save_course = (e) => {
|
||||
validate_mandatory();
|
||||
let tags = $(".tags button")
|
||||
.map((i, el) => $(el).text().trim())
|
||||
.get();
|
||||
@@ -75,12 +82,45 @@ const save_course = (e) => {
|
||||
indicator: "green",
|
||||
});
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
window.location.href = `/courses/${data.message}/edit`;
|
||||
}, 1000);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const validate_mandatory = () => {
|
||||
let fields = $(".field-label.reqd");
|
||||
fields.each((i, el) => {
|
||||
let input = $(el).closest(".field-group").find(".field-input");
|
||||
if (input.length && input.val().trim() == "") {
|
||||
if (input.siblings(".error-message").length == 0) {
|
||||
let error = document.createElement("p");
|
||||
error.classList.add("error-message");
|
||||
error.innerText = `Please enter a ${$(el).text().trim()}`;
|
||||
$(error).insertAfter($(input));
|
||||
}
|
||||
scroll_to_element(input);
|
||||
throw "Mandatory field missing";
|
||||
}
|
||||
});
|
||||
console.log(this.description.fields_dict["description"].value);
|
||||
if (!this.description.fields_dict["description"].value) {
|
||||
scroll_to_element("#description");
|
||||
frappe.throw(__(`Please enter a description`));
|
||||
}
|
||||
};
|
||||
|
||||
const scroll_to_element = (element) => {
|
||||
if ($(element).length) {
|
||||
$([document.documentElement, document.body]).animate(
|
||||
{
|
||||
scrollTop: $(element).offset().top - 100,
|
||||
},
|
||||
1000
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const make_editor = () => {
|
||||
this.description = new frappe.ui.FieldGroup({
|
||||
fields: [
|
||||
|
||||
@@ -128,7 +128,7 @@
|
||||
|
||||
<div class="field-group">
|
||||
<div>
|
||||
<div class="field-label">
|
||||
<div class="field-label reqd">
|
||||
{{ _("Chapter Title") }}
|
||||
</div>
|
||||
<div class="field-description">
|
||||
|
||||
@@ -35,6 +35,7 @@ const show_chapter_modal = (e) => {
|
||||
};
|
||||
|
||||
const save_chapter = (e) => {
|
||||
validate_mandatory();
|
||||
let parent = $("#chapter-modal");
|
||||
|
||||
frappe.call({
|
||||
@@ -58,6 +59,16 @@ const save_chapter = (e) => {
|
||||
});
|
||||
};
|
||||
|
||||
const validate_mandatory = () => {
|
||||
if (!$("#chapter-title").val()) {
|
||||
let error = $("p")
|
||||
.addClass("error-message")
|
||||
.text("Chapter title is required");
|
||||
$(error).insertAfter("#chapter-title");
|
||||
throw __("Chapter title is required");
|
||||
}
|
||||
};
|
||||
|
||||
const setSortable = (el) => {
|
||||
new Sortable(el, {
|
||||
group: "drag",
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
import frappe
|
||||
from lms.lms.utils import get_chapters
|
||||
from frappe import _
|
||||
from lms.lms.utils import get_chapters, can_create_courses
|
||||
|
||||
|
||||
def get_context(context):
|
||||
context.no_cache = 1
|
||||
|
||||
if not can_create_courses():
|
||||
message = "You do not have permission to access this page."
|
||||
if frappe.session.user == "Guest":
|
||||
message = "Please login to access this page."
|
||||
|
||||
raise frappe.PermissionError(_(message))
|
||||
|
||||
context.course = frappe.db.get_value(
|
||||
"LMS Course", frappe.form_dict["course"], ["name", "title"], as_dict=True
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user