From fa774b0db23a38319cc3a19a3386c18d6ac16820 Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Fri, 19 Jul 2024 20:05:28 +0530 Subject: [PATCH 01/29] feat: quiz creation --- frontend/src/pages/QuizCreation.vue | 62 +++++++++++++ frontend/src/pages/Quizzes.vue | 117 +++++++++++++++++++++++++ frontend/src/router.js | 11 +++ frontend/src/translation.js | 1 + lms/lms/doctype/lms_quiz/lms_quiz.json | 6 +- 5 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 frontend/src/pages/QuizCreation.vue create mode 100644 frontend/src/pages/Quizzes.vue diff --git a/frontend/src/pages/QuizCreation.vue b/frontend/src/pages/QuizCreation.vue new file mode 100644 index 00000000..99c7447e --- /dev/null +++ b/frontend/src/pages/QuizCreation.vue @@ -0,0 +1,62 @@ + + diff --git a/frontend/src/pages/Quizzes.vue b/frontend/src/pages/Quizzes.vue new file mode 100644 index 00000000..113fde84 --- /dev/null +++ b/frontend/src/pages/Quizzes.vue @@ -0,0 +1,117 @@ + + diff --git a/frontend/src/router.js b/frontend/src/router.js index 3b53ce19..d93d207a 100644 --- a/frontend/src/router.js +++ b/frontend/src/router.js @@ -141,6 +141,17 @@ const routes = [ component: () => import('@/pages/Badge.vue'), props: true, }, + { + path: '/quizzes', + name: 'Quizzes', + component: () => import('@/pages/Quizzes.vue'), + }, + { + path: '/quizzes/:quizID', + name: 'QuizCreation', + component: () => import('@/pages/QuizCreation.vue'), + props: true, + }, ] let router = createRouter({ diff --git a/frontend/src/translation.js b/frontend/src/translation.js index 0f9911dc..f6b9050b 100644 --- a/frontend/src/translation.js +++ b/frontend/src/translation.js @@ -2,6 +2,7 @@ import { createResource } from 'frappe-ui' export default function translationPlugin(app) { app.config.globalProperties.__ = translate + window.__ = translate if (!window.translatedMessages) fetchTranslations() } diff --git a/lms/lms/doctype/lms_quiz/lms_quiz.json b/lms/lms/doctype/lms_quiz/lms_quiz.json index 9c1b8e95..38d23b9a 100644 --- a/lms/lms/doctype/lms_quiz/lms_quiz.json +++ b/lms/lms/doctype/lms_quiz/lms_quiz.json @@ -74,6 +74,7 @@ "default": "1", "fieldname": "show_answers", "fieldtype": "Check", + "in_standard_filter": 1, "label": "Show Answers" }, { @@ -98,6 +99,8 @@ { "fieldname": "passing_percentage", "fieldtype": "Int", + "in_list_view": 1, + "in_standard_filter": 1, "label": "Passing Percentage", "non_negative": 1, "reqd": 1 @@ -110,6 +113,7 @@ "default": "0", "fieldname": "total_marks", "fieldtype": "Int", + "in_list_view": 1, "label": "Total Marks", "non_negative": 1, "read_only": 1, @@ -133,7 +137,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2024-06-27 22:03:48.576489", + "modified": "2024-07-19 18:21:26.681501", "modified_by": "Administrator", "module": "LMS", "name": "LMS Quiz", From a450c846a6996e1d340cb32885b7a8c45a72b345 Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Mon, 29 Jul 2024 19:44:04 +0530 Subject: [PATCH 02/29] feat: questions table --- .gitmodules | 3 + frappe-ui | 2 +- frontend/src/components/Modals/Question.vue | 30 ++++ frontend/src/pages/QuizCreation.vue | 132 +++++++++++++++--- frontend/src/pages/Quizzes.vue | 25 ++-- frontend/yarn.lock | 29 ++-- .../lms_quiz_question/lms_quiz_question.json | 23 ++- .../certificate_request_creation.html | 2 +- package.json | 2 +- 9 files changed, 199 insertions(+), 49 deletions(-) create mode 100644 .gitmodules create mode 100644 frontend/src/components/Modals/Question.vue diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..e82154a1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "frappe-ui"] + path = frappe-ui + url = https://github.com/pateljannat/frappe-ui diff --git a/frappe-ui b/frappe-ui index aa44431c..a349ab07 160000 --- a/frappe-ui +++ b/frappe-ui @@ -1 +1 @@ -Subproject commit aa44431c185b1e4563f2ebf6af380c7743d2cd4c +Subproject commit a349ab070a73a3d22ead6a33374c9fe44f6ecf57 diff --git a/frontend/src/components/Modals/Question.vue b/frontend/src/components/Modals/Question.vue new file mode 100644 index 00000000..bdecfc4c --- /dev/null +++ b/frontend/src/components/Modals/Question.vue @@ -0,0 +1,30 @@ + + \ No newline at end of file diff --git a/frontend/src/pages/QuizCreation.vue b/frontend/src/pages/QuizCreation.vue index 99c7447e..dd2b13a5 100644 --- a/frontend/src/pages/QuizCreation.vue +++ b/frontend/src/pages/QuizCreation.vue @@ -4,31 +4,97 @@ > -
- - - - - +
+ +
+
+ {{ __("Details") }} +
+
+
+ + + +
+
+ + +
+
+
+ + +
+
+ {{ __("Settings") }} +
+
+ + + +
+
+ + +
+
+
+ {{ __("Questions") }} +
+ +
+ + + + + + + +
+ {{ item }} +
+
+
+
+
+
+ \ No newline at end of file + diff --git a/frontend/src/pages/QuizCreation.vue b/frontend/src/pages/QuizCreation.vue index dd2b13a5..6a92150f 100644 --- a/frontend/src/pages/QuizCreation.vue +++ b/frontend/src/pages/QuizCreation.vue @@ -8,12 +8,15 @@
- {{ __("Details") }} + {{ __('Details') }}
- +
- +
- {{ __("Settings") }} + {{ __('Settings') }}
- - - + + +
@@ -45,28 +60,35 @@
- {{ __("Questions") }} + {{ __('Questions') }}
-
- + - +
{{ item }} @@ -77,15 +99,27 @@
- + + diff --git a/frontend/src/pages/QuizCreation.vue b/frontend/src/pages/QuizCreation.vue index b53b835e..90f6fdcb 100644 --- a/frontend/src/pages/QuizCreation.vue +++ b/frontend/src/pages/QuizCreation.vue @@ -3,6 +3,9 @@ class="sticky top-0 z-10 flex items-center justify-between border-b bg-white px-3 py-2.5 sm:px-5" > +
@@ -10,107 +13,128 @@
{{ __('Details') }}
-
-
- - - + +
+
+
+ + +
+
+ + +
-
- - -
-
-
- -
-
- {{ __('Settings') }} -
-
- - - -
-
- - -
-
-
- {{ __('Questions') }} + +
+
+ {{ __('Settings') }} +
+
+ + + +
- -
- - - - - - +
+
+
+ {{ __('Questions') }} +
+ +
+ - -
+ + + + - {{ item }} -
-
- {{ item }} -
-
- - -
+ +
+ {{ item }} +
+
+ {{ item }} +
+
+ + + +
+
- + diff --git a/frontend/src/pages/Quizzes.vue b/frontend/src/pages/Quizzes.vue index e7e75b30..3a678e91 100644 --- a/frontend/src/pages/Quizzes.vue +++ b/frontend/src/pages/Quizzes.vue @@ -3,12 +3,21 @@ class="sticky top-0 z-10 flex items-center justify-between border-b bg-white px-3 py-2.5 sm:px-5" > - + + +
{ + if (!user.data?.is_moderator && !user.data?.is_instructor) { + router.push({ name: 'Courses' }) + } +}) const quizFilter = computed(() => { if (user.data?.is_moderator) return {} @@ -68,6 +85,7 @@ const quizzes = createListResource({ fields: ['name', 'title', 'passing_percentage', 'total_marks'], auto: true, cache: ['quizzes', user.data?.name], + orderBy: 'modified desc', onSuccess(data) { data.forEach((row) => {}) }, diff --git a/lms/lms/doctype/lms_quiz/lms_quiz.py b/lms/lms/doctype/lms_quiz/lms_quiz.py index ef7f6243..33abac89 100644 --- a/lms/lms/doctype/lms_quiz/lms_quiz.py +++ b/lms/lms/doctype/lms_quiz/lms_quiz.py @@ -5,7 +5,7 @@ import json import frappe from frappe import _ from frappe.model.document import Document -from frappe.utils import cstr, comma_and +from frappe.utils import cstr, comma_and, cint from fuzzywuzzy import fuzz from lms.lms.doctype.course_lesson.course_lesson import save_progress from lms.lms.utils import ( @@ -30,12 +30,12 @@ class LMSQuiz(Document): ) def validate_limit(self): - if self.limit_questions_to and self.limit_questions_to >= len(self.questions): + if self.limit_questions_to and cint(self.limit_questions_to) >= len(self.questions): frappe.throw( _("Limit cannot be greater than or equal to the number of questions in the quiz.") ) - if self.limit_questions_to and self.limit_questions_to < len(self.questions): + if self.limit_questions_to and cint(self.limit_questions_to) < len(self.questions): marks = [question.marks for question in self.questions] if len(set(marks)) > 1: frappe.throw(_("All questions should have the same marks if the limit is set.")) @@ -43,10 +43,10 @@ class LMSQuiz(Document): def calculate_total_marks(self): if self.limit_questions_to: self.total_marks = sum( - question.marks for question in self.questions[: self.limit_questions_to] + question.marks for question in self.questions[: cint(self.limit_questions_to)] ) else: - self.total_marks = sum(question.marks for question in self.questions) + self.total_marks = sum(cint(question.marks) for question in self.questions) def autoname(self): if not self.name: From cdb028c69cbe9a443deb67916ec9b9a81e18afe4 Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Mon, 5 Aug 2024 15:12:45 +0530 Subject: [PATCH 06/29] feat: settings --- frontend/src/components/Modals/Settings.vue | 25 +++++++++++++++++++++ frontend/src/components/UserDropdown.vue | 16 +++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 frontend/src/components/Modals/Settings.vue diff --git a/frontend/src/components/Modals/Settings.vue b/frontend/src/components/Modals/Settings.vue new file mode 100644 index 00000000..d02152f2 --- /dev/null +++ b/frontend/src/components/Modals/Settings.vue @@ -0,0 +1,25 @@ + + diff --git a/frontend/src/components/UserDropdown.vue b/frontend/src/components/UserDropdown.vue index 210114af..efece54d 100644 --- a/frontend/src/components/UserDropdown.vue +++ b/frontend/src/components/UserDropdown.vue @@ -56,6 +56,7 @@ + diff --git a/frontend/src/components/BatchOverlay.vue b/frontend/src/components/BatchOverlay.vue index 2eb225c2..670548a4 100644 --- a/frontend/src/components/BatchOverlay.vue +++ b/frontend/src/components/BatchOverlay.vue @@ -81,7 +81,7 @@ { if (!user.data) window.location.href = '/login' if (props.batchName != 'new') { batchDetail.reload() + } else { + capture("batch_form_opened") } window.addEventListener('keydown', keyboardShortcut) }) @@ -377,6 +380,7 @@ const createNewBatch = () => { {}, { onSuccess(data) { + capture("batch_created") router.push({ name: 'BatchDetail', params: { @@ -447,7 +451,7 @@ const breadcrumbs = computed(() => { } crumbs.push({ label: props.batchName == 'new' ? 'New Batch' : 'Edit Batch', - route: { name: 'BatchCreation', params: { batchName: props.batchName } }, + route: { name: 'BatchForm', params: { batchName: props.batchName } }, }) return crumbs }) diff --git a/frontend/src/pages/Batches.vue b/frontend/src/pages/Batches.vue index 2ace50f6..77e73c5d 100644 --- a/frontend/src/pages/Batches.vue +++ b/frontend/src/pages/Batches.vue @@ -19,7 +19,7 @@ diff --git a/frontend/src/pages/CreateCourse.vue b/frontend/src/pages/CourseForm.vue similarity index 98% rename from frontend/src/pages/CreateCourse.vue rename to frontend/src/pages/CourseForm.vue index dbd33dda..4e92db90 100644 --- a/frontend/src/pages/CreateCourse.vue +++ b/frontend/src/pages/CourseForm.vue @@ -227,6 +227,7 @@ import { FileText, X } from 'lucide-vue-next' import { useRouter } from 'vue-router' import CourseOutline from '@/components/CourseOutline.vue' import MultiSelect from '@/components/Controls/MultiSelect.vue' +import { capture } from "@/telemetry"; const user = inject('$user') const newTag = ref('') @@ -268,6 +269,8 @@ onMounted(() => { if (props.courseName !== 'new') { courseResource.reload() + } else { + capture("course_form_opened") } window.addEventListener('keydown', keyboardShortcut) }) @@ -388,9 +391,10 @@ const submitCourse = () => { } else { courseCreationResource.submit(course, { onSuccess(data) { + capture("course_created") showToast('Success', 'Course created successfully', 'check') router.push({ - name: 'CreateCourse', + name: 'CourseForm', params: { courseName: data.name }, }) }, @@ -489,7 +493,7 @@ const breadcrumbs = computed(() => { } crumbs.push({ label: props.courseName == 'new' ? 'New Course' : 'Edit Course', - route: { name: 'CreateCourse', params: { courseName: props.courseName } }, + route: { name: 'CourseForm', params: { courseName: props.courseName } }, }) return crumbs }) diff --git a/frontend/src/pages/Courses.vue b/frontend/src/pages/Courses.vue index c367d151..299cf434 100644 --- a/frontend/src/pages/Courses.vue +++ b/frontend/src/pages/Courses.vue @@ -22,7 +22,7 @@
import('@/pages/CreateCourse.vue'), + name: 'CourseForm', + component: () => import('@/pages/CourseForm.vue'), props: true, }, { @@ -109,8 +109,8 @@ const routes = [ }, { path: '/batches/:batchName/edit', - name: 'BatchCreation', - component: () => import('@/pages/BatchCreation.vue'), + name: 'BatchForm', + component: () => import('@/pages/BatchForm.vue'), props: true, }, { diff --git a/frontend/src/telemetry.ts b/frontend/src/telemetry.ts new file mode 100644 index 00000000..dfd5e3b6 --- /dev/null +++ b/frontend/src/telemetry.ts @@ -0,0 +1,98 @@ +import { useStorage } from "@vueuse/core"; +import { call } from "frappe-ui"; +import "../../../frappe/frappe/public/js/lib/posthog.js"; + +const APP = "lms"; +const SITENAME = window.location.hostname; + +declare global { + interface Window { + posthog: any; + } +} + +const telemetry = useStorage("telemetry", { + enabled: false, + project_id: "", + host: "", +}); + +export async function init() { + await set_enabled(); + if (!telemetry.value.enabled) return; + try { + await set_credentials(); + window.posthog.init(telemetry.value.project_id, { + api_host: telemetry.value.host, + autocapture: false, + person_profiles: "always", + capture_pageview: true, + capture_pageleave: true, + disable_session_recording: false, + session_recording: { + maskAllInputs: false, + maskInputOptions: { + password: true, + }, + }, + loaded: (posthog) => { + window.posthog = posthog; + window.posthog.identify(SITENAME); + }, + }); + } catch (e) { + console.trace("Failed to initialize telemetry", e); + telemetry.value.enabled = false; + } +} + +async function set_enabled() { + if (telemetry.value.enabled) return; + + await call("lms.lms.telemetry.is_enabled").then((res) => { + telemetry.value.enabled = res; + }); +} + +async function set_credentials() { + if (!telemetry.value.enabled) return; + if (telemetry.value.project_id && telemetry.value.host) return; + + await call("lms.lms.telemetry.get_credentials").then((res) => { + telemetry.value.project_id = res.project_id; + telemetry.value.host = res.telemetry_host; + }); +} + +interface CaptureOptions { + data: { + user: string; + [key: string]: string | number | boolean | object; + }; +} + +export function capture( + event: string, + options: CaptureOptions = { data: { user: "" } } +) { + if (!telemetry.value.enabled) return; + window.posthog.capture(`${APP}_${event}`, options); +} + +export function recordSession() { + if (!telemetry.value.enabled) return; + if (window.posthog && window.posthog.__loaded) { + window.posthog.startSessionRecording(); + } +} + +export function stopSession() { + if (!telemetry.value.enabled) return; + if ( + window.posthog && + window.posthog.__loaded && + window.posthog.sessionRecordingStarted() + ) { + window.posthog.stopSessionRecording(); + } +} diff --git a/frontend/src/utils/index.js b/frontend/src/utils/index.js index e732e09f..2123d981 100644 --- a/frontend/src/utils/index.js +++ b/frontend/src/utils/index.js @@ -424,7 +424,7 @@ export function getSidebarLinks() { 'Courses', 'CourseDetail', 'Lesson', - 'CreateCourse', + 'CourseForm', 'LessonForm', ], }, @@ -432,7 +432,7 @@ export function getSidebarLinks() { label: 'Batches', icon: 'Users', to: 'Batches', - activeFor: ['Batches', 'BatchDetail', 'Batch', 'BatchCreation'], + activeFor: ['Batches', 'BatchDetail', 'Batch', 'BatchForm'], }, { label: 'Certified Participants', diff --git a/lms/lms/api.py b/lms/lms/api.py index a27557e7..c25e49da 100644 --- a/lms/lms/api.py +++ b/lms/lms/api.py @@ -560,23 +560,3 @@ def get_categories(doctype, filters): categoryOptions.append({"label": category, "value": category}) return categoryOptions - -@frappe.whitelist(allow_guest=True) -def get_posthog_api_key(): - should_record_session - return { - "project_id": frappe.conf.get(POSTHOG_PROJECT_FIELD), - "posthog_host": frappe.conf.get(POSTHOG_HOST_FIELD), - "enable_telemetry": frappe.get_system_settings("enable_telemetry"), - "should_record_session": should_record_session(), - } - -def should_record_session(): - start_datetime = frappe.boot.sysdefaults.session_recording_start - start_datetime = get_datetime(start_datetime) - if not start_datetime: - return False - - now = now_datetime() - # if user allowed recording only record for first 2 hours, never again. - return time_diff(now, start_datetime) < 120; \ No newline at end of file diff --git a/lms/lms/telemetry.py b/lms/lms/telemetry.py new file mode 100644 index 00000000..c704351f --- /dev/null +++ b/lms/lms/telemetry.py @@ -0,0 +1,16 @@ +import frappe + +@frappe.whitelist() +def is_enabled(): + return bool( + frappe.get_system_settings("enable_telemetry") + and frappe.conf.get("posthog_host") + and frappe.conf.get("posthog_project_id") + ) + +@frappe.whitelist() +def get_credentials(): + return { + "project_id": frappe.conf.get("posthog_project_id"), + "telemetry_host": frappe.conf.get("posthog_host"), + } diff --git a/package.json b/package.json index 3d55b554..f5231fac 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "cypress-file-upload": "^5.0.8" }, "dependencies": { - "posthog-js": "^1.154.4", "pre-commit": "^1.2.2" } } From 0335b3b4d0151ca9c255025aadcf76306d72fff1 Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Mon, 12 Aug 2024 17:38:59 +0530 Subject: [PATCH 21/29] chore: fixed linters --- frontend/src/pages/BatchForm.vue | 6 +++--- frontend/src/pages/CourseForm.vue | 6 +++--- lms/lms/telemetry.py | 20 +++++++++++--------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/frontend/src/pages/BatchForm.vue b/frontend/src/pages/BatchForm.vue index 74a9101a..c5fd6d80 100644 --- a/frontend/src/pages/BatchForm.vue +++ b/frontend/src/pages/BatchForm.vue @@ -236,7 +236,7 @@ import MultiSelect from '@/components/Controls/MultiSelect.vue' import { useRouter } from 'vue-router' import { getFileSize, showToast } from '../utils' import { X, FileText } from 'lucide-vue-next' -import { capture } from "@/telemetry" +import { capture } from '@/telemetry' const router = useRouter() const user = inject('$user') @@ -276,7 +276,7 @@ onMounted(() => { if (props.batchName != 'new') { batchDetail.reload() } else { - capture("batch_form_opened") + capture('batch_form_opened') } window.addEventListener('keydown', keyboardShortcut) }) @@ -380,7 +380,7 @@ const createNewBatch = () => { {}, { onSuccess(data) { - capture("batch_created") + capture('batch_created') router.push({ name: 'BatchDetail', params: { diff --git a/frontend/src/pages/CourseForm.vue b/frontend/src/pages/CourseForm.vue index 4e92db90..9f7f2935 100644 --- a/frontend/src/pages/CourseForm.vue +++ b/frontend/src/pages/CourseForm.vue @@ -227,7 +227,7 @@ import { FileText, X } from 'lucide-vue-next' import { useRouter } from 'vue-router' import CourseOutline from '@/components/CourseOutline.vue' import MultiSelect from '@/components/Controls/MultiSelect.vue' -import { capture } from "@/telemetry"; +import { capture } from '@/telemetry' const user = inject('$user') const newTag = ref('') @@ -270,7 +270,7 @@ onMounted(() => { if (props.courseName !== 'new') { courseResource.reload() } else { - capture("course_form_opened") + capture('course_form_opened') } window.addEventListener('keydown', keyboardShortcut) }) @@ -391,7 +391,7 @@ const submitCourse = () => { } else { courseCreationResource.submit(course, { onSuccess(data) { - capture("course_created") + capture('course_created') showToast('Success', 'Course created successfully', 'check') router.push({ name: 'CourseForm', diff --git a/lms/lms/telemetry.py b/lms/lms/telemetry.py index c704351f..7e4de8ec 100644 --- a/lms/lms/telemetry.py +++ b/lms/lms/telemetry.py @@ -1,16 +1,18 @@ import frappe + @frappe.whitelist() def is_enabled(): - return bool( - frappe.get_system_settings("enable_telemetry") - and frappe.conf.get("posthog_host") - and frappe.conf.get("posthog_project_id") - ) + return bool( + frappe.get_system_settings("enable_telemetry") + and frappe.conf.get("posthog_host") + and frappe.conf.get("posthog_project_id") + ) + @frappe.whitelist() def get_credentials(): - return { - "project_id": frappe.conf.get("posthog_project_id"), - "telemetry_host": frappe.conf.get("posthog_host"), - } + return { + "project_id": frappe.conf.get("posthog_project_id"), + "telemetry_host": frappe.conf.get("posthog_host"), + } From a744a43d14d5ccaa9ad7e1720677fd2bef3d576d Mon Sep 17 00:00:00 2001 From: Frappe PR Bot Date: Mon, 12 Aug 2024 12:32:42 +0000 Subject: [PATCH 22/29] chore(release): Bumped to Version 2.1.0 --- lms/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lms/__init__.py b/lms/__init__.py index 8c0d5d5b..9aa3f903 100644 --- a/lms/__init__.py +++ b/lms/__init__.py @@ -1 +1 @@ -__version__ = "2.0.0" +__version__ = "2.1.0" From 05ebe4b78747786cb483cff246964d5171f752ec Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Mon, 12 Aug 2024 20:09:56 +0530 Subject: [PATCH 23/29] fix: lesson structure issue --- frontend/src/components/CourseOutline.vue | 1 + frontend/src/components/Discussions.vue | 4 ++-- .../src/components/Modals/DiscussionModal.vue | 4 ++-- frontend/src/utils/index.js | 16 ++++++++++++++++ 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/CourseOutline.vue b/frontend/src/components/CourseOutline.vue index e5d3a98b..59da7574 100644 --- a/frontend/src/components/CourseOutline.vue +++ b/frontend/src/components/CourseOutline.vue @@ -41,6 +41,7 @@
{{ __(title) }} @@ -65,7 +65,7 @@ diff --git a/frontend/src/components/Modals/Settings.vue b/frontend/src/components/Modals/Settings.vue index d02152f2..e1d8a36d 100644 --- a/frontend/src/components/Modals/Settings.vue +++ b/frontend/src/components/Modals/Settings.vue @@ -1,25 +1,270 @@ diff --git a/frontend/src/components/SettingDetails.vue b/frontend/src/components/SettingDetails.vue new file mode 100644 index 00000000..fe4abe9d --- /dev/null +++ b/frontend/src/components/SettingDetails.vue @@ -0,0 +1,89 @@ + + + diff --git a/frontend/src/components/UserDropdown.vue b/frontend/src/components/UserDropdown.vue index efece54d..67c4bc96 100644 --- a/frontend/src/components/UserDropdown.vue +++ b/frontend/src/components/UserDropdown.vue @@ -1,5 +1,5 @@ diff --git a/lms/templates/search_course/search_course.js b/lms/templates/search_course/search_course.js deleted file mode 100644 index 2ba8d04d..00000000 --- a/lms/templates/search_course/search_course.js +++ /dev/null @@ -1,72 +0,0 @@ -frappe.ready(() => { - $("#search-course").keyup((e) => { - search_course(e); - }); - - $("#open-search").click((e) => { - show_search_bar(e); - }); - - $("#search-modal").on("hidden.bs.modal", () => { - hide_search_bar(); - }); - - $(document).keydown(function (e) { - if ((e.metaKey || e.ctrlKey) && e.key == "k") { - show_search_bar(e); - } - }); -}); - -const search_course = (e) => { - let input = $(e.currentTarget).val(); - if (input == window.input) return; - window.input = input; - - if (input.length < 3 || input.trim() == "") { - $(".result-row").remove(); - return; - } - - frappe.call({ - method: "lms.lms.doctype.lms_course.lms_course.search_course", - args: { - text: input, - }, - callback: (data) => { - render_course_list(data); - }, - }); -}; - -const render_course_list = (data) => { - let courses = data.message; - $(".result-row").remove(); - - if (!courses.length) { - let element = ` - ${__("No result found")} - `; - $(element).insertAfter("#search-course"); - return; - } - - for (let i in courses) { - let element = ` - ${courses[i].title} - `; - $(element).insertAfter("#search-course"); - } -}; - -const show_search_bar = (e) => { - $("#search-modal").modal("show"); - setTimeout(() => { - $("#search-course").focus(); - }, 1000); -}; - -const hide_search_bar = (e) => { - $("#search-course").val(""); - $(".result-row").remove(); -}; From 14f36d0c64af03cee0921a6f494066059ed7a4eb Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Tue, 13 Aug 2024 18:59:39 +0530 Subject: [PATCH 27/29] chore: removed unnecessary file --- frontend/src/components/Fields.vue | 214 ----------------------------- 1 file changed, 214 deletions(-) delete mode 100644 frontend/src/components/Fields.vue diff --git a/frontend/src/components/Fields.vue b/frontend/src/components/Fields.vue deleted file mode 100644 index 5fe1abd3..00000000 --- a/frontend/src/components/Fields.vue +++ /dev/null @@ -1,214 +0,0 @@ - - - From afbf64170a4b38b3d6c2c95fdfef6fb81470c83b Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Tue, 13 Aug 2024 19:03:17 +0530 Subject: [PATCH 28/29] fix: removed old settings --- lms/lms/api.py | 26 ------------ .../doctype/lms_settings/lms_settings.json | 42 +------------------ 2 files changed, 1 insertion(+), 67 deletions(-) diff --git a/lms/lms/api.py b/lms/lms/api.py index 8d7c2c4d..d04ec783 100644 --- a/lms/lms/api.py +++ b/lms/lms/api.py @@ -562,29 +562,3 @@ def get_categories(doctype, filters): categoryOptions.append({"label": category, "value": category}) return categoryOptions - - -@frappe.whitelist() -def get_fields(doctype: str, allow_all_fieldtypes: bool = False): - not_allowed_fieldtypes = list(frappe.model.no_value_fields) + ["Read Only"] - if allow_all_fieldtypes: - not_allowed_fieldtypes = [] - fields = frappe.get_meta(doctype).fields - - _fields = [] - - for field in fields: - if field.fieldtype not in not_allowed_fieldtypes and field.fieldname: - _fields.append( - { - "label": field.label, - "type": field.fieldtype, - "value": field.fieldname, - "options": field.options, - "mandatory": field.reqd, - "read_only": field.read_only, - "hidden": field.hidden, - } - ) - - return _fields diff --git a/lms/lms/doctype/lms_settings/lms_settings.json b/lms/lms/doctype/lms_settings/lms_settings.json index 5d0af7a3..68b5ddde 100644 --- a/lms/lms/doctype/lms_settings/lms_settings.json +++ b/lms/lms/doctype/lms_settings/lms_settings.json @@ -10,14 +10,9 @@ "column_break_zdel", "unsplash_access_key", "livecode_url", - "course_settings_section", - "search_placeholder", - "column_break_iqxy", - "portal_course_creation", "section_break_szgq", "send_calendar_invite_for_evaluations", "show_day_view", - "allow_student_progress", "column_break_2", "show_dashboard", "show_courses", @@ -48,7 +43,6 @@ "notifications", "section_break_qlss", "sidebar_items", - "mentor_request_tab", "mentor_request_section", "mentor_request_creation", "mentor_request_status_update", @@ -98,11 +92,6 @@ "fieldtype": "Column Break", "label": "Show Tab in Batch" }, - { - "fieldname": "search_placeholder", - "fieldtype": "Data", - "label": "Course List Search Bar Placeholder" - }, { "default": "0", "fieldname": "terms_of_use", @@ -139,13 +128,6 @@ "fieldname": "column_break_12", "fieldtype": "Column Break" }, - { - "default": "Course Creator Role", - "fieldname": "portal_course_creation", - "fieldtype": "Select", - "label": "Course Creation Access Through Website To", - "options": "Course Creator Role\nAnyone" - }, { "fieldname": "column_break_9", "fieldtype": "Column Break" @@ -203,19 +185,6 @@ "fieldtype": "Tab Break", "label": "Signup Settings" }, - { - "fieldname": "mentor_request_tab", - "fieldtype": "Tab Break", - "hidden": 1, - "label": "Mentor Request" - }, - { - "default": "0", - "fieldname": "allow_student_progress", - "fieldtype": "Check", - "hidden": 1, - "label": "Allow students to see each others progress in class" - }, { "fieldname": "payment_section", "fieldtype": "Section Break" @@ -230,15 +199,6 @@ "fieldname": "column_break_cfcv", "fieldtype": "Column Break" }, - { - "fieldname": "course_settings_section", - "fieldtype": "Section Break", - "label": "Course Settings" - }, - { - "fieldname": "column_break_iqxy", - "fieldtype": "Column Break" - }, { "fieldname": "razorpay_key", "fieldtype": "Data", @@ -423,7 +383,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2024-06-27 21:57:02.193336", + "modified": "2024-08-13 19:02:58.714080", "modified_by": "Administrator", "module": "LMS", "name": "LMS Settings", From 6c18f9a02f4fcf2f5b6107d9f95e796392b7387b Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Wed, 14 Aug 2024 10:44:11 +0530 Subject: [PATCH 29/29] ci: automated release PR --- .github/workflows/make_release_pr.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/make_release_pr.yml diff --git a/.github/workflows/make_release_pr.yml b/.github/workflows/make_release_pr.yml new file mode 100644 index 00000000..b8064ea2 --- /dev/null +++ b/.github/workflows/make_release_pr.yml @@ -0,0 +1,27 @@ +name: Create weekly release +on: + schedule: + # 13:00 UTC -> 7pm IST on every Wednesday + - cron: '30 4 * * 3' + workflow_dispatch: + +jobs: + release: + name: Release + runs-on: ubuntu-latest + strategy: + fail-fast: false + + steps: + - uses: octokit/request-action@v2.x + with: + route: POST /repos/{owner}/{repo}/pulls + owner: frappe + repo: lms + title: |- + "chore: merge 'develop' into 'main'" + body: "Automated weekly release" + base: main + head: develop + env: + GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} \ No newline at end of file