From 0f314bc4e35fc7d56b39c1946df967ca4e38104d Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Thu, 22 Dec 2022 15:47:03 +0530 Subject: [PATCH 1/4] feat: new search ui --- lms/lms/doctype/lms_course/lms_course.py | 12 +--- lms/lms/md.py | 2 +- lms/public/css/style.css | 55 +++++++++++++++---- .../search_course/search_course.html | 9 ++- lms/templates/search_course/search_course.js | 28 +++++++++- lms/www/base.html | 6 ++ lms/www/courses/index.html | 6 +- 7 files changed, 92 insertions(+), 26 deletions(-) create mode 100644 lms/www/base.html diff --git a/lms/lms/doctype/lms_course/lms_course.py b/lms/lms/doctype/lms_course/lms_course.py index a420dec3..6299bced 100644 --- a/lms/lms/doctype/lms_course/lms_course.py +++ b/lms/lms/doctype/lms_course/lms_course.py @@ -167,7 +167,6 @@ def reindex_exercises(doc): @frappe.whitelist(allow_guest=True) def search_course(text): - search_courses = [] courses = frappe.get_all( "LMS Course", filters={"published": True}, @@ -177,17 +176,8 @@ def search_course(text): "short_introduction": ["like", f"%{text}%"], "description": ["like", f"%{text}%"], }, + fields=["name", "title", "image"], ) - - """ for course in courses: - search_courses.append(frappe.get_doc("LMS Course", course)) """ - - """ template = frappe.render_template("lms/templates/course_list.html", { - "title": _("Search Results"), - "courses": search_courses, - "widgets": Widgets() - }) """ - return courses diff --git a/lms/lms/md.py b/lms/lms/md.py index 1a6b9ed7..e7830722 100644 --- a/lms/lms/md.py +++ b/lms/lms/md.py @@ -114,7 +114,7 @@ def sanitize_html(html, macro): any broken tags. This makes sures that all those things are fixed before passing to the etree parser. """ - soup = BeautifulSoup(html, features="lxml") + soup = BeautifulSoup(html, features="html5lib") nodes = soup.body.children classname = "" if macro == "YouTubeVideo": diff --git a/lms/public/css/style.css b/lms/public/css/style.css index 1f9ea4ac..e5b219be 100644 --- a/lms/public/css/style.css +++ b/lms/public/css/style.css @@ -929,17 +929,17 @@ pre { } .search { - background-image: url(/assets/frappe/icons/timeless/search.svg); - border: none; - border-radius: var(--border-radius-md); - font-size: var(--text-sm); - padding: 0.625rem 0.75rem; - height: 36px; - background-repeat: no-repeat; - text-indent: 1.5rem; - background-position: 1rem 0.7rem; - width: 30%; - box-shadow: var(--shadow-sm); + border: none; + border-radius: var(--border-radius-md); + font-size: var(--text-base); + padding: 0.625rem 0.75rem; + height: 36px; + width: 80%; + box-shadow: var(--shadow-base); +} + +.search:focus { + outline: none; } .course-search-header { @@ -1918,3 +1918,36 @@ select { cursor: pointer; margin-right: 1rem; } + +.modal-container { + display: none; + position: fixed; + z-index: 10; + left: 0; + top: 0; + width: 100%; + height: 100%; + overflow: auto; + background-color: rgb(0,0,0); + background-color: rgba(0,0,0,0.4); +} + +.modal-inner { + background: #ffffff; + margin: 15% auto 2rem; +} + + +.close { + color: #aaa; + float: right; + font-size: 28px; + font-weight: bold; +} + +.close:hover, +.close:focus { + color: black; + text-decoration: none; + cursor: pointer; +} diff --git a/lms/templates/search_course/search_course.html b/lms/templates/search_course/search_course.html index 3de74cb2..2cc370a3 100644 --- a/lms/templates/search_course/search_course.html +++ b/lms/templates/search_course/search_course.html @@ -1,7 +1,14 @@ {% set search_placeholder = frappe.db.get_single_value("LMS Settings", "search_placeholder") %} {% set portal_course_creation = frappe.db.get_single_value("LMS Settings", "portal_course_creation") %} - + + + +
×
diff --git a/lms/templates/search_course/search_course.js b/lms/templates/search_course/search_course.js index 9deba304..4f199165 100644 --- a/lms/templates/search_course/search_course.js +++ b/lms/templates/search_course/search_course.js @@ -6,6 +6,14 @@ frappe.ready(() => { $(".close-search-empty-state").click((e) => { close_search_empty_state(e); }); + + $("#open-search").click((e) => { + show_search_bar(); + }); + + $("#search-course").focusout((e) => { + hide_search_bar(); + }); }); const search_course = (e) => { @@ -28,7 +36,14 @@ const search_course = (e) => { text: input, }, callback: (data) => { - render_course_list(data.message); + let courses = data.message; + $(".result-row").remove(); + for (let i in courses) { + let element = `
+ ${courses[i].title} +
`; + $("#search-result").append(element); + } }, }); }; @@ -72,3 +87,14 @@ const close_search_empty_state = (e) => { $(".search-empty-state").addClass("hide"); $("#search-course").val(""); }; + +const show_search_bar = () => { + $("#open-search").addClass("hide"); + $("#search-modal").css("display", "block"); + $("#search-course").focus(); +}; + +const hide_search_bar = () => { + $("#open-search").removeClass("hide"); + $("#search-modal").css("display", "none"); +}; diff --git a/lms/www/base.html b/lms/www/base.html new file mode 100644 index 00000000..90ae1167 --- /dev/null +++ b/lms/www/base.html @@ -0,0 +1,6 @@ +{% extends "templates/base.html" %} + +{% block content %} +
Janant
+

Reder

+{% endblock %} diff --git a/lms/www/courses/index.html b/lms/www/courses/index.html index 1d618468..52aaeece 100644 --- a/lms/www/courses/index.html +++ b/lms/www/courses/index.html @@ -22,7 +22,7 @@ {% else %} - + {% include "lms/templates/search_course/search_course.html" %}
{% if frappe.session.user != "Guest" %} @@ -36,6 +36,10 @@ {{ _("Create a Course") }} {% endif %} + + + {{ _("Search") }} +
From 46075130ab5c50e99e6431610eb292ba79177efd Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Mon, 26 Dec 2022 13:24:29 +0530 Subject: [PATCH 2/4] fix: search ux --- lms/lms/doctype/lms_course/lms_course.py | 2 +- lms/public/css/style.css | 44 ++++++++-- .../search_course/search_course.html | 23 ++---- lms/templates/search_course/search_course.js | 81 +++++++------------ 4 files changed, 74 insertions(+), 76 deletions(-) diff --git a/lms/lms/doctype/lms_course/lms_course.py b/lms/lms/doctype/lms_course/lms_course.py index 6299bced..0019f743 100644 --- a/lms/lms/doctype/lms_course/lms_course.py +++ b/lms/lms/doctype/lms_course/lms_course.py @@ -176,7 +176,7 @@ def search_course(text): "short_introduction": ["like", f"%{text}%"], "description": ["like", f"%{text}%"], }, - fields=["name", "title", "image"], + fields=["name", "title"], ) return courses diff --git a/lms/public/css/style.css b/lms/public/css/style.css index e5b219be..0cf5472e 100644 --- a/lms/public/css/style.css +++ b/lms/public/css/style.css @@ -929,13 +929,16 @@ pre { } .search { + background-image: url(/assets/frappe/icons/timeless/search.svg); + background-repeat: no-repeat; + background-position: 1rem; + text-indent: 1rem; border: none; - border-radius: var(--border-radius-md); - font-size: var(--text-base); - padding: 0.625rem 0.75rem; - height: 36px; - width: 80%; - box-shadow: var(--shadow-base); + border-radius: var(--border-radius-md); + font-size: var(--text-base); + padding: 1.5rem; + height: 36px; + width: 100%; } .search:focus { @@ -1934,7 +1937,9 @@ select { .modal-inner { background: #ffffff; - margin: 15% auto 2rem; + margin: 15% auto 2rem; + width: 70%; + border-radius: var(--border-radius-md); } @@ -1951,3 +1956,28 @@ select { text-decoration: none; cursor: pointer; } + +.result-row { + display: block; + padding: 1rem; + border-top: 1px solid var(--gray-300); + font-weight: 500; + color: var(--gray-900); + font-size: var(--text-base); + cursor: pointer; +} + +.result-row:hover { + color: inherit; + text-decoration: none; +} + +.search-modal .modal-dialog { + max-width: 70%; + margin: 15% auto !important; +} + +.search-modal .modal-body { + padding: 0 !important; + margin: 0 !important; +} diff --git a/lms/templates/search_course/search_course.html b/lms/templates/search_course/search_course.html index 2cc370a3..e6d2ac46 100644 --- a/lms/templates/search_course/search_course.html +++ b/lms/templates/search_course/search_course.html @@ -2,22 +2,13 @@ {% set portal_course_creation = frappe.db.get_single_value("LMS Settings", "portal_course_creation") %} - - - -
- × -
- -
-
-
{{ _("No results found") }}
-
{{ _("Try some other keyword or explore our list of courses.") }}
+ - diff --git a/lms/templates/search_course/search_course.js b/lms/templates/search_course/search_course.js index 4f199165..fee2b63a 100644 --- a/lms/templates/search_course/search_course.js +++ b/lms/templates/search_course/search_course.js @@ -8,25 +8,22 @@ frappe.ready(() => { }); $("#open-search").click((e) => { - show_search_bar(); + show_search_bar(e); }); - $("#search-course").focusout((e) => { + $('#search-modal').on('hidden.bs.modal', () => { hide_search_bar(); }); + }); const search_course = (e) => { let input = $(e.currentTarget).val(); - if (input == window.input) return; - window.input = input; if (input.length < 3 || input.trim() == "") { - $(".course-card").removeClass("hide"); - $(".search-empty-state").addClass("hide"); - fix_heading_styles(); + $(".result-row").remove(); return; } @@ -36,51 +33,30 @@ const search_course = (e) => { text: input, }, callback: (data) => { - let courses = data.message; - $(".result-row").remove(); - for (let i in courses) { - let element = `
- ${courses[i].title} -
`; - $("#search-result").append(element); - } + render_course_list(data); }, }); }; -const render_course_list = (courses) => { - fix_heading_styles(); - $(".search-empty-state").addClass("hide"); +const render_course_list = (data) => { + let courses = data.message; + $(".result-row").remove(); - if (!courses.length) { - $(".course-card").removeClass("hide"); - $(".search-empty-state").removeClass("hide"); + if (! courses.length) { + let element = ` + ${__("No result found")} + `; + $(element).insertAfter("#search-course"); return; } - $(".course-card").addClass("hide"); - for (course in courses) { - $("[data-course=" + courses[course].name + "]").removeClass("hide"); + + for (let i in courses) { + let element = ` + ${courses[i].title} + `; + $(element).insertAfter("#search-course"); } - - const visible_live_courses = $(".live-courses .course-card").not(".hide"); - const visible_upcoming_courses = $(".upcoming-courses .course-card").not( - ".hide" - ); - - if (!visible_live_courses.length) { - $(".live-courses .course-home-headings").addClass("hide"); - $(".upcoming-courses").removeClass("mt-10"); - } - - if (!visible_upcoming_courses.length) { - $(".upcoming-courses .course-home-headings").addClass("hide"); - } -}; - -const fix_heading_styles = () => { - $(".course-home-headings").removeClass("hide"); - $(".upcoming-courses").addClass("mt-10"); }; const close_search_empty_state = (e) => { @@ -88,13 +64,14 @@ const close_search_empty_state = (e) => { $("#search-course").val(""); }; -const show_search_bar = () => { - $("#open-search").addClass("hide"); - $("#search-modal").css("display", "block"); - $("#search-course").focus(); -}; +const show_search_bar = (e) => { + $("#search-modal").modal("show"); + setTimeout(() => { + $("#search-course").focus(); + }, 1000) +} -const hide_search_bar = () => { - $("#open-search").removeClass("hide"); - $("#search-modal").css("display", "none"); -}; +const hide_search_bar = (e) => { + $("#search-course").val(""); + $(".result-row").remove(); +} From 263b3ec476c79b2010c05b8b656b71d112ddadd5 Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Mon, 26 Dec 2022 13:27:57 +0530 Subject: [PATCH 3/4] fix: formatting --- lms/templates/search_course/search_course.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lms/templates/search_course/search_course.js b/lms/templates/search_course/search_course.js index fee2b63a..cb562ccd 100644 --- a/lms/templates/search_course/search_course.js +++ b/lms/templates/search_course/search_course.js @@ -11,10 +11,9 @@ frappe.ready(() => { show_search_bar(e); }); - $('#search-modal').on('hidden.bs.modal', () => { + $("#search-modal").on("hidden.bs.modal", () => { hide_search_bar(); }); - }); const search_course = (e) => { @@ -42,7 +41,7 @@ const render_course_list = (data) => { let courses = data.message; $(".result-row").remove(); - if (! courses.length) { + if (!courses.length) { let element = ` ${__("No result found")} `; @@ -50,7 +49,6 @@ const render_course_list = (data) => { return; } - for (let i in courses) { let element = ` ${courses[i].title} @@ -68,10 +66,10 @@ const show_search_bar = (e) => { $("#search-modal").modal("show"); setTimeout(() => { $("#search-course").focus(); - }, 1000) -} + }, 1000); +}; const hide_search_bar = (e) => { $("#search-course").val(""); $(".result-row").remove(); -} +}; From bd0b7a828658bce67f6ec37187ed7bc292b6924b Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Mon, 26 Dec 2022 13:56:03 +0530 Subject: [PATCH 4/4] fix: removed unused code --- lms/lms/md.py | 2 +- lms/public/css/style.css | 50 +++++-------------- .../search_course/search_course.html | 2 +- lms/templates/search_course/search_course.js | 9 ---- lms/www/base.html | 6 --- 5 files changed, 14 insertions(+), 55 deletions(-) delete mode 100644 lms/www/base.html diff --git a/lms/lms/md.py b/lms/lms/md.py index e7830722..1a6b9ed7 100644 --- a/lms/lms/md.py +++ b/lms/lms/md.py @@ -114,7 +114,7 @@ def sanitize_html(html, macro): any broken tags. This makes sures that all those things are fixed before passing to the etree parser. """ - soup = BeautifulSoup(html, features="html5lib") + soup = BeautifulSoup(html, features="lxml") nodes = soup.body.children classname = "" if macro == "YouTubeVideo": diff --git a/lms/public/css/style.css b/lms/public/css/style.css index 0cf5472e..1697920b 100644 --- a/lms/public/css/style.css +++ b/lms/public/css/style.css @@ -930,14 +930,23 @@ pre { .search { background-image: url(/assets/frappe/icons/timeless/search.svg); + border: none; + border-radius: var(--border-radius-md); + font-size: var(--text-sm); + padding: 0.625rem 0.75rem; + height: 36px; background-repeat: no-repeat; + text-indent: 1.5rem; + background-position: 1rem 0.7rem; + width: 30%; + box-shadow: var(--shadow-sm); +} + +.search-course { background-position: 1rem; text-indent: 1rem; - border: none; - border-radius: var(--border-radius-md); font-size: var(--text-base); padding: 1.5rem; - height: 36px; width: 100%; } @@ -1922,41 +1931,6 @@ select { margin-right: 1rem; } -.modal-container { - display: none; - position: fixed; - z-index: 10; - left: 0; - top: 0; - width: 100%; - height: 100%; - overflow: auto; - background-color: rgb(0,0,0); - background-color: rgba(0,0,0,0.4); -} - -.modal-inner { - background: #ffffff; - margin: 15% auto 2rem; - width: 70%; - border-radius: var(--border-radius-md); -} - - -.close { - color: #aaa; - float: right; - font-size: 28px; - font-weight: bold; -} - -.close:hover, -.close:focus { - color: black; - text-decoration: none; - cursor: pointer; -} - .result-row { display: block; padding: 1rem; diff --git a/lms/templates/search_course/search_course.html b/lms/templates/search_course/search_course.html index e6d2ac46..22bcd2a2 100644 --- a/lms/templates/search_course/search_course.html +++ b/lms/templates/search_course/search_course.html @@ -6,7 +6,7 @@ diff --git a/lms/templates/search_course/search_course.js b/lms/templates/search_course/search_course.js index cb562ccd..9d2580fa 100644 --- a/lms/templates/search_course/search_course.js +++ b/lms/templates/search_course/search_course.js @@ -3,10 +3,6 @@ frappe.ready(() => { search_course(e); }); - $(".close-search-empty-state").click((e) => { - close_search_empty_state(e); - }); - $("#open-search").click((e) => { show_search_bar(e); }); @@ -57,11 +53,6 @@ const render_course_list = (data) => { } }; -const close_search_empty_state = (e) => { - $(".search-empty-state").addClass("hide"); - $("#search-course").val(""); -}; - const show_search_bar = (e) => { $("#search-modal").modal("show"); setTimeout(() => { diff --git a/lms/www/base.html b/lms/www/base.html deleted file mode 100644 index 90ae1167..00000000 --- a/lms/www/base.html +++ /dev/null @@ -1,6 +0,0 @@ -{% extends "templates/base.html" %} - -{% block content %} -
Janant
-

Reder

-{% endblock %}