From a507ab425c223f2122bf7e5a4d4bcdc6a722e27c Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Tue, 7 Apr 2026 17:54:03 +0530 Subject: [PATCH] fix: improved list for assignments and programming exercises --- frontend/src/pages/Assignments.vue | 138 ++++++++++++++---- .../ProgrammingExerciseForm.vue | 4 +- .../ProgrammingExercises.vue | 58 ++++---- frontend/src/pages/Quizzes.vue | 4 +- 4 files changed, 143 insertions(+), 61 deletions(-) diff --git a/frontend/src/pages/Assignments.vue b/frontend/src/pages/Assignments.vue index 4f1a74e4..038a1aa2 100644 --- a/frontend/src/pages/Assignments.vue +++ b/frontend/src/pages/Assignments.vue @@ -20,18 +20,15 @@ -
+
-
- {{ __('{0} Assignments').format(assignmentCount) }} +
+ {{ __('{0} Assignments').format(assignments.data?.length) }}
-
+
+ + + + + + + + + + + + + -
- +
+
+ {{ assignments.data?.length }} {{ __('of') }} + {{ totalAssignments.data }} {{ __('Assignments') }} +
{ assignmentID.value = 'new' showAssignmentForm.value = true } - getAssignmentCount() titleFilter.value = router.currentRoute.value.query.title typeFilter.value = router.currentRoute.value.query.type }) @@ -123,6 +179,9 @@ watch([titleFilter, typeFilter], () => { }, }) reloadAssignments() + totalAssignments.update({ + filters: assignmentFilter.value, + }) }) const reloadAssignments = () => { @@ -137,7 +196,7 @@ const assignmentFilter = computed(() => { if (titleFilter.value) { filters.title = ['like', `%${titleFilter.value}%`] } - if (typeFilter.value) { + if (typeFilter.value && typeFilter.value.trim() !== '') { filters.type = typeFilter.value } return filters @@ -145,51 +204,60 @@ const assignmentFilter = computed(() => { const assignments = createListResource({ doctype: 'LMS Assignment', - fields: ['name', 'title', 'type', 'creation', 'question', 'course'], + fields: ['name', 'title', 'type', 'modified', 'question', 'course'], orderBy: 'modified desc', cache: ['assignments'], transform(data) { return data.map((row) => { return { ...row, - creation: dayjs(row.creation).fromNow(), + modified: dayjs(row.modified).format('DD MMM YYYY'), } }) }, }) +const totalAssignments = createResource({ + url: 'frappe.client.get_count', + params: { + doctype: 'LMS Assignment', + filters: assignmentFilter.value, + }, + auto: true, + cache: ['assignments_count', user.data?.name], + onError(err) { + toast.error(err.messages?.[0] || err) + console.error(err) + }, +}) + const assignmentColumns = computed(() => { return [ { label: __('Title'), key: 'title', - width: 2, + width: 1, + icon: 'file-text', }, { label: __('Type'), key: 'type', width: 1, align: 'left', + icon: 'tag', }, { - label: __('Created'), - key: 'creation', + label: __('Modified'), + key: 'modified', width: 1, align: 'right', + icon: 'clock', }, ] }) -const getAssignmentCount = () => { - call('frappe.client.get_count', { - doctype: 'LMS Assignment', - }).then((data) => { - assignmentCount.value = data - }) -} - const assignmentTypes = computed(() => { - let types = ['', 'Document', 'Image', 'PDF', 'URL', 'Text'] + let types = [' ', 'Document', 'Image', 'PDF', 'URL', 'Text'] return types.map((type) => { return { label: __(type), @@ -198,6 +266,14 @@ const assignmentTypes = computed(() => { }) }) +const deleteAssignment = (selections, unselectAll) => { + Array.from(selections).forEach(async (assignmentName) => { + await assignments.delete.submit(assignmentName) + }) + unselectAll() + toast.success(__('Assignments deleted successfully')) +} + const breadcrumbs = computed(() => [ { label: __('Assignments'), diff --git a/frontend/src/pages/ProgrammingExercises/ProgrammingExerciseForm.vue b/frontend/src/pages/ProgrammingExercises/ProgrammingExerciseForm.vue index 89036fe7..1852e8fa 100644 --- a/frontend/src/pages/ProgrammingExercises/ProgrammingExerciseForm.vue +++ b/frontend/src/pages/ProgrammingExercises/ProgrammingExerciseForm.vue @@ -132,6 +132,7 @@ import ChildTable from '@/components/Controls/ChildTable.vue' const show = defineModel() const exercises = defineModel('exercises') +const totalExercises = defineModel('totalExercises') const isDirty = ref(false) const originalTestCaseCount = ref(0) @@ -150,7 +151,6 @@ const languageOptions = [ const props = withDefaults( defineProps<{ exerciseID: string - getExerciseCount: () => Promise }>(), { exerciseID: 'new', @@ -257,7 +257,7 @@ const createNewExercise = (close: () => void) => { close() isDirty.value = false exercises.value?.reload() - props.getExerciseCount() + totalExercises.value.reload() toast.success(__('Programming Exercise created successfully')) }, onError(err: any) { diff --git a/frontend/src/pages/ProgrammingExercises/ProgrammingExercises.vue b/frontend/src/pages/ProgrammingExercises/ProgrammingExercises.vue index a6090dc9..c4923f06 100644 --- a/frontend/src/pages/ProgrammingExercises/ProgrammingExercises.vue +++ b/frontend/src/pages/ProgrammingExercises/ProgrammingExercises.vue @@ -37,7 +37,7 @@
- {{ __('{0} Exercises').format(exerciseCount) }} + {{ __('{0} Exercises').format(exercises.data?.length) }}