Skip to content

Commit 736ce8e

Browse files
authored
Merge pull request #1636 from frappe/develop
chore: merge 'develop' into 'main'
2 parents 3409049 + c15c637 commit 736ce8e

142 files changed

Lines changed: 58896 additions & 13076 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/helper/install_dependencies.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ echo "Setting Up System Dependencies..."
55

66
sudo apt update
77
sudo apt remove mysql-server mysql-client
8-
sudo apt-get install libcups2-dev redis-server mariadb-client
8+
sudo apt-get install libcups2-dev redis-server mariadb-client libmariadb-dev
99

1010
install_wkhtmltopdf() {
1111
wget -q https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ Replace the following parameters with your values:
118118

119119
The script will set up a production-ready instance of Frappe Learning with all the necessary configurations in about 5 minutes.
120120

121+
**Note:** To avoid a `404 Page Not Found` error:
122+
- If hosting on a **public server**, make sure your DNS **A record** points to your server's IP.
123+
- If hosting **locally**, map your domain to `127.0.0.1` in your `/etc/hosts` file:
124+
121125
## Development Setup
122126

123127
### Docker

cypress/e2e/batch_creation.cy.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ describe("Batch Creation", () => {
2323
const randomEmail = `testuser_${dateNow}@example.com`;
2424
const randomName = `Test User ${dateNow}`;
2525

26-
cy.get("input[placeholder='Email']").type(randomEmail);
27-
cy.get("input[placeholder='First Name']").type(randomName);
26+
cy.get("input[placeholder='jane@doe.com']").type(randomEmail);
27+
cy.get("input[placeholder='Jane']").type(randomName);
2828
cy.get("button").contains("Add").click();
2929

3030
// Add evaluator
@@ -39,15 +39,15 @@ describe("Batch Creation", () => {
3939
.click();
4040
const randomEvaluator = `evaluator${dateNow}@example.com`;
4141

42-
cy.get("input[placeholder='Email']").type(randomEvaluator);
42+
cy.get("input[placeholder='jane@doe.com']").type(randomEvaluator);
4343
cy.get("button").contains("Add").click();
4444
cy.get("div").contains(randomEvaluator).should("be.visible").click();
4545

4646
cy.visit("/lms/batches");
4747
cy.closeOnboardingModal();
4848

4949
// Create a batch
50-
cy.get("button").contains("New").click();
50+
cy.get("button").contains("Create").click();
5151
cy.wait(500);
5252
cy.url().should("include", "/batches/new/edit");
5353
cy.get("label").contains("Title").type("Test Batch");

cypress/e2e/course_creation.cy.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ describe("Course Creation", () => {
88
cy.closeOnboardingModal();
99

1010
// Create a course
11-
cy.get("button").contains("New").click();
11+
cy.get("button").contains("Create").click();
1212
cy.wait(500);
1313
cy.url().should("include", "/courses/new/edit");
1414

frontend/components.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ declare module 'vue' {
1919
AssignmentForm: typeof import('./src/components/Modals/AssignmentForm.vue')['default']
2020
AudioBlock: typeof import('./src/components/AudioBlock.vue')['default']
2121
Autocomplete: typeof import('./src/components/Controls/Autocomplete.vue')['default']
22+
BadgeAssignmentForm: typeof import('./src/components/Settings/BadgeAssignmentForm.vue')['default']
23+
BadgeAssignments: typeof import('./src/components/Settings/BadgeAssignments.vue')['default']
24+
BadgeForm: typeof import('./src/components/Settings/BadgeForm.vue')['default']
25+
Badges: typeof import('./src/components/Settings/Badges.vue')['default']
2226
BatchCard: typeof import('./src/components/BatchCard.vue')['default']
2327
BatchCourseModal: typeof import('./src/components/Modals/BatchCourseModal.vue')['default']
2428
BatchCourses: typeof import('./src/components/BatchCourses.vue')['default']
@@ -32,12 +36,15 @@ declare module 'vue' {
3236
Categories: typeof import('./src/components/Settings/Categories.vue')['default']
3337
CertificationLinks: typeof import('./src/components/CertificationLinks.vue')['default']
3438
ChapterModal: typeof import('./src/components/Modals/ChapterModal.vue')['default']
39+
ChildTable: typeof import('./src/components/Controls/ChildTable.vue')['default']
40+
Code: typeof import('./src/components/Controls/Code.vue')['default']
3541
CodeEditor: typeof import('./src/components/Controls/CodeEditor.vue')['default']
3642
CollapseSidebar: typeof import('./src/components/Icons/CollapseSidebar.vue')['default']
3743
CourseCard: typeof import('./src/components/CourseCard.vue')['default']
3844
CourseCardOverlay: typeof import('./src/components/CourseCardOverlay.vue')['default']
3945
CourseInstructors: typeof import('./src/components/CourseInstructors.vue')['default']
4046
CourseOutline: typeof import('./src/components/CourseOutline.vue')['default']
47+
CourseProgressSummary: typeof import('./src/components/Modals/CourseProgressSummary.vue')['default']
4148
CourseReviews: typeof import('./src/components/CourseReviews.vue')['default']
4249
CreateOutline: typeof import('./src/components/CreateOutline.vue')['default']
4350
DateRange: typeof import('./src/components/Common/DateRange.vue')['default']
@@ -96,10 +103,12 @@ declare module 'vue' {
96103
Tags: typeof import('./src/components/Tags.vue')['default']
97104
UnsplashImageBrowser: typeof import('./src/components/UnsplashImageBrowser.vue')['default']
98105
UpcomingEvaluations: typeof import('./src/components/UpcomingEvaluations.vue')['default']
106+
Uploader: typeof import('./src/components/Controls/Uploader.vue')['default']
99107
UploadPlugin: typeof import('./src/components/UploadPlugin.vue')['default']
100108
UserAvatar: typeof import('./src/components/UserAvatar.vue')['default']
101109
UserDropdown: typeof import('./src/components/UserDropdown.vue')['default']
102110
VideoBlock: typeof import('./src/components/VideoBlock.vue')['default']
111+
VideoStatistics: typeof import('./src/components/Modals/VideoStatistics.vue')['default']
103112
ZoomAccountModal: typeof import('./src/components/Modals/ZoomAccountModal.vue')['default']
104113
ZoomSettings: typeof import('./src/components/Settings/ZoomSettings.vue')['default']
105114
}

frontend/package.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
"copy-html-entry": "cp ../lms/public/frontend/index.html ../lms/www/lms.html"
1111
},
1212
"dependencies": {
13+
"@codemirror/lang-html": "^6.4.9",
14+
"@codemirror/lang-javascript": "^6.2.4",
15+
"@codemirror/lang-json": "^6.0.1",
16+
"@codemirror/lang-python": "^6.2.1",
1317
"@editorjs/checklist": "^1.6.0",
1418
"@editorjs/code": "^2.9.0",
1519
"@editorjs/editorjs": "^2.29.0",
@@ -24,20 +28,22 @@
2428
"ace-builds": "^1.36.2",
2529
"apexcharts": "^4.3.0",
2630
"chart.js": "^4.4.1",
27-
"codemirror-editor-vue3": "^2.8.0",
31+
"codemirror": "^6.0.1",
2832
"dayjs": "^1.11.6",
2933
"feather-icons": "^4.28.0",
30-
"frappe-ui": "^0.1.147",
34+
"frappe-ui": "^0.1.163",
3135
"highlight.js": "^11.11.1",
3236
"lucide-vue-next": "^0.383.0",
3337
"markdown-it": "^14.0.0",
3438
"pinia": "^2.0.33",
3539
"plyr": "^3.7.8",
3640
"socket.io-client": "^4.7.2",
3741
"tailwindcss": "3.4.15",
42+
"thememirror": "^2.0.1",
3843
"typescript": "^5.7.2",
3944
"vue": "^3.4.23",
4045
"vue-chartjs": "^5.3.0",
46+
"vue-codemirror": "^6.1.1",
4147
"vue-draggable-next": "^2.2.1",
4248
"vue-router": "^4.0.12",
4349
"vue3-apexcharts": "^1.8.0",

frontend/public/Remove.mp4

1.07 MB
Binary file not shown.

frontend/src/components/AppSidebar.vue

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ import {
225225
IntermediateStepModal,
226226
} from 'frappe-ui/frappe'
227227
228-
const { user, sidebarSettings } = sessionStore()
228+
const { user } = sessionStore()
229229
const { userResource } = usersStore()
230230
let sidebarStore = useSidebar()
231231
const socket = inject('$socket')
@@ -236,6 +236,7 @@ const isModerator = ref(false)
236236
const isInstructor = ref(false)
237237
const pageToEdit = ref(null)
238238
const settingsStore = useSettings()
239+
const { sidebarSettings } = settingsStore
239240
const showOnboarding = ref(false)
240241
const showIntermediateModal = ref(false)
241242
const currentStep = ref({})
@@ -313,7 +314,7 @@ const addNotifications = () => {
313314
314315
const addQuizzes = () => {
315316
if (isInstructor.value || isModerator.value) {
316-
sidebarLinks.value.push({
317+
sidebarLinks.value.splice(4, 0, {
317318
label: 'Quizzes',
318319
icon: 'CircleHelp',
319320
to: 'Quizzes',
@@ -329,7 +330,7 @@ const addQuizzes = () => {
329330
330331
const addAssignments = () => {
331332
if (isInstructor.value || isModerator.value) {
332-
sidebarLinks.value.push({
333+
sidebarLinks.value.splice(5, 0, {
333334
label: 'Assignments',
334335
icon: 'Pencil',
335336
to: 'Assignments',

frontend/src/components/AssessmentPlugin.vue

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,24 @@
22
<Dialog
33
v-model="show"
44
:options="{
5+
title:
6+
type == 'quiz'
7+
? __('Add a quiz to your lesson')
8+
: __('Add an assignment to your lesson'),
59
size: 'xl',
10+
actions: [
11+
{
12+
label: __('Save'),
13+
variant: 'solid',
14+
onClick: () => {
15+
addAssessment()
16+
},
17+
},
18+
],
619
}"
720
>
8-
<template #body>
9-
<div class="p-5 space-y-4">
10-
<div v-if="type == 'quiz'" class="text-lg font-semibold">
11-
{{ __('Add a quiz to your lesson') }}
12-
</div>
13-
<div v-else class="text-lg font-semibold">
14-
{{ __('Add an assignment to your lesson') }}
15-
</div>
21+
<template #body-content>
22+
<div class="">
1623
<div>
1724
<Link
1825
v-if="type == 'quiz'"
@@ -29,17 +36,12 @@
2936
:onCreate="(value, close) => redirectToForm()"
3037
/>
3138
</div>
32-
<div class="flex justify-end space-x-2">
33-
<Button variant="solid" @click="addAssessment()">
34-
{{ __('Save') }}
35-
</Button>
36-
</div>
3739
</div>
3840
</template>
3941
</Dialog>
4042
</template>
4143
<script setup>
42-
import { Dialog, Button } from 'frappe-ui'
44+
import { Dialog } from 'frappe-ui'
4345
import { onMounted, ref, nextTick } from 'vue'
4446
import Link from '@/components/Controls/Link.vue'
4547

frontend/src/components/Assessments.vue

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
<template #default="{ column, item }">
4141
<ListRowItem :item="row[column.key]" :align="column.align">
4242
<div v-if="column.key == 'assessment_type'">
43-
{{ row[column.key] == 'LMS Quiz' ? 'Quiz' : 'Assignment' }}
43+
{{ getAssessmentTypeLabel(row[column.key]) }}
4444
</div>
4545
<div v-else-if="column.key == 'title'">
4646
{{ row[column.key] }}
@@ -172,6 +172,24 @@ const getRowRoute = (row) => {
172172
},
173173
}
174174
}
175+
} else if (row.assessment_type == 'LMS Programming Exercise') {
176+
if (row.submission) {
177+
return {
178+
name: 'ProgrammingExerciseSubmission',
179+
params: {
180+
exerciseID: row.assessment_name,
181+
submissionID: row.submission.name,
182+
},
183+
}
184+
} else {
185+
return {
186+
name: 'ProgrammingExerciseSubmission',
187+
params: {
188+
exerciseID: row.assessment_name,
189+
submissionID: 'new',
190+
},
191+
}
192+
}
175193
} else {
176194
return {
177195
name: 'QuizPage',
@@ -213,12 +231,22 @@ const getAssessmentColumns = () => {
213231
}
214232
215233
const getStatusTheme = (status) => {
216-
if (status === 'Pass') {
234+
if (status === 'Pass' || status === 'Passed') {
217235
return 'green'
218236
} else if (status === 'Not Graded') {
219237
return 'orange'
220238
} else {
221239
return 'red'
222240
}
223241
}
242+
243+
const getAssessmentTypeLabel = (type) => {
244+
if (type == 'LMS Assignment') {
245+
return __('Assignment')
246+
} else if (type == 'LMS Quiz') {
247+
return __('Quiz')
248+
} else if (type == 'LMS Programming Exercise') {
249+
return __('Programming Exercise')
250+
}
251+
}
224252
</script>

0 commit comments

Comments
 (0)