Skip to content

Commit 8405d46

Browse files
authored
Merge pull request #846 from bcgov/feature/GRAD2-3491
GRAD2-3491 - Adds student course and exam history tab
2 parents d59b7d0 + 3e518a6 commit 8405d46

File tree

3 files changed

+186
-2
lines changed

3 files changed

+186
-2
lines changed
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
<template>
2+
<v-data-table
3+
:sortBy="sortBy"
4+
:items="courseHistory"
5+
:headers="courseHeaders"
6+
:items-per-page="'-1'"
7+
item-value="id"
8+
>
9+
<template v-slot:headers="{ columns, isSorted, getSortIcon, toggleSort }">
10+
<tr>
11+
<template v-for="column in columns" :key="column.key">
12+
<th>
13+
<div class="d-flex align-center">
14+
<span
15+
class="me-2 cursor-pointer"
16+
@click="toggleSort(column)"
17+
v-text="column.title"
18+
:title="column.description"
19+
></span>
20+
<v-icon
21+
v-if="isSorted(column)"
22+
:icon="getSortIcon(column)"
23+
color="medium-emphasis"
24+
></v-icon>
25+
</div>
26+
</th>
27+
</template>
28+
</tr>
29+
</template>
30+
<template v-slot:expanded-row="{ item }">
31+
<tr>
32+
<td :colspan="courseHeaders.length">
33+
<v-row dense>
34+
<v-col
35+
v-for="field in courseExamFields"
36+
:key="field.key"
37+
class="text-center"
38+
:title="field.description"
39+
>
40+
<div class="text-caption font-weight-bold">{{ field.label }}</div>
41+
<div class="text-body-2">{{ item.courseExam[field.key] ?? '' }}</div>
42+
</v-col>
43+
</v-row>
44+
</td>
45+
</tr>
46+
</template>
47+
<template
48+
v-slot:item.data-table-expand="{
49+
item,
50+
internalItem,
51+
toggleExpand,
52+
isExpanded,
53+
}"
54+
>
55+
<td v-if="!!item.courseExam">
56+
<v-btn
57+
variant="text"
58+
density="comfortable"
59+
size="small"
60+
@click="toggleExpand(internalItem)"
61+
class="v-data-table__expand-icon"
62+
:class="{ 'v-data-table__expand-icon--active': isExpanded }"
63+
:icon="
64+
isExpanded(internalItem)
65+
? 'mdi-chevron-down'
66+
: 'mdi-chevron-right'
67+
"
68+
>
69+
</v-btn>
70+
</td>
71+
</template>
72+
<template v-slot:item.activityCode="{ item }">
73+
<i>{{ item.activityCode }}</i> -
74+
{{ item.activityDescription }}
75+
</template>
76+
<template v-slot:item.updateDate="{ item }">
77+
{{ $filters.formatTime(item.updateDate) }}
78+
</template>
79+
</v-data-table>
80+
</template>
81+
82+
<script>
83+
84+
import {mapActions, mapState} from "pinia";
85+
import {useStudentStore} from "@/store/modules/student";
86+
87+
export default {
88+
props: {},
89+
computed: {
90+
...mapState(useStudentStore, {
91+
studentId: "getStudentId",
92+
courseHistory: "getStudentCourseAuditHistory"
93+
}),
94+
},
95+
data: function () {
96+
return {
97+
courseChangeHistory: [],
98+
courseHeaders: [
99+
{ key: "data-table-expand", title: "" },
100+
{ key: "updateDate", title: "Date", width: "115px" },
101+
{ key: "activityCode", title: "Change" },
102+
{ key: "updateUser", title: "Update User", sortable: true },
103+
{ key: "courseDetails.courseCode", title: "Code" },
104+
{ key: "courseDetails.courseLevel", title: "Level" },
105+
{ key: "courseSession", title: "Session" },
106+
{ key: "interimPercent", title: "%", description: "Interim Percent" },
107+
{ key: "interimLetterGrade", title: "LG", description: "Interim Letter Grade" },
108+
{ key: "finalPercent", title: "%", description: "Final Percent" },
109+
{ key: "finalLetterGrade", title: "LG", description: "Final Letter Grade" },
110+
{ key: "credits", title: "Credits" },
111+
{ key: "equivOrChallenge", title: "EC", description: "Equivalent or Challenge" },
112+
{ key: "fineArtsAppliedSkills", title: "AS", description: "Fine Arts or Applied Skills" },
113+
{ key: "customizedCourseName", title: "Custom Course Title" },
114+
{
115+
key: "relatedCourseDetails.courseCode",
116+
title: "Related Course",
117+
value: (item) => {
118+
const code = item.relatedCourseDetails?.courseCode ?? "";
119+
const level = item.relatedCourseDetails?.courseLevel ?? "";
120+
return code && level ? `${code} ${level}` : code || level || "";
121+
}
122+
}
123+
],
124+
courseExamFields: [
125+
{ label: "School %", key: "schoolPercentage", description: "School Percentage" },
126+
{ label: "Best School %", key: "bestSchoolPercentage", description: "Best School Percentage" },
127+
{ label: "Best Exam %", key: "bestExamPercentage" , description: "Best Exam Percentage"},
128+
{ label: "Exam %", key: "examPercentage", description: "Exam Percentage" },
129+
{ label: "To Write?", key: "toWriteFlag", description: "Will Write Exam" },
130+
{ label: "Wrote?", key: "wroteFlag", description: "Wrote Exam" },
131+
{ label: "Special Case", key: "specialCase" },
132+
],
133+
sortBy: [{ key: "updateDate", order: "desc" }],
134+
}
135+
},
136+
created() {
137+
this.loadStudentCourseHistory(this.studentId);
138+
},
139+
methods: {
140+
...mapActions(useStudentStore, [
141+
"loadStudentCourseHistory",
142+
]),
143+
}
144+
}
145+
</script>

frontend/src/components/StudentProfile/AuditHistory/StudentAuditHistory.vue

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,15 @@
1919
>Optional Program Change History</v-chip
2020
></v-tab
2121
>
22+
<v-tab value="courseChangeHistory" v-if="enableCRUD()">
23+
<v-chip
24+
class="text-none"
25+
color="primary"
26+
:variant="selectedTab === 'courseChangeHistory' ? 'flat' : 'outlined'"
27+
>
28+
Course Change History
29+
</v-chip>
30+
</v-tab>
2231
</v-tabs>
2332
<v-card-text class="px-0">
2433
<v-window v-model="selectedTab">
@@ -258,20 +267,25 @@
258267
</template>
259268
</v-data-table>
260269
</v-window-item>
270+
<v-window-item value="courseChangeHistory">
271+
<CourseChangeHistory />
272+
</v-window-item>
261273
</v-window>
262274
</v-card-text>
263275
</v-card>
264276
</template>
265277

266278
<script>
267-
import { useStudentStore } from "../../../store/modules/student";
279+
import { useStudentStore } from "@/store/modules/student";
268280
import { mapState } from "pinia";
269281
import DisplayTable from "@/components/DisplayTable.vue";
270-
import { useAppStore } from "../../../store/modules/app";
282+
import { useAppStore } from "@/store/modules/app";
283+
import CourseChangeHistory from "@/components/StudentProfile/AuditHistory/CourseChangeHistory.vue";
271284
272285
export default {
273286
name: "StudentAuditHistory",
274287
components: {
288+
CourseChangeHistory,
275289
DisplayTable: DisplayTable,
276290
},
277291
props: {},
@@ -284,6 +298,7 @@ export default {
284298
}),
285299
...mapState(useAppStore, {
286300
getSchoolById: "getSchoolById",
301+
enableCRUD: "enableCRUD",
287302
}),
288303
studentHistoryWithPrevData() {
289304
this.studentHistory.sort(

frontend/src/store/modules/student.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export const useStudentStore = defineStore("student", {
4141
careerPrograms: [],
4242
auditHistory: [],
4343
auditHistoryOptionalPrograms: [],
44+
auditHistoryCourses: [],
4445
},
4546
editedGradStatus: {
4647
programCompletionDate: "",
@@ -291,6 +292,23 @@ export const useStudentStore = defineStore("student", {
291292
}
292293
});
293294
},
295+
loadStudentCourseHistory(studentId) {
296+
StudentService.getStudentCourseHistory(studentId)
297+
.then((response) => {
298+
this.setStudentCourseAuditHistory(response.data);
299+
})
300+
.catch((error) => {
301+
if (error?.response?.status) {
302+
this.snackbarStore.showSnackbar(
303+
"ERROR " + error?.response?.statusText,
304+
"error",
305+
10000,
306+
"There was an error with the Student Service (getting the Student Course History): " +
307+
error?.response?.status
308+
);
309+
}
310+
});
311+
},
294312
unsetStudent() {
295313
this.student.profile = {};
296314
this.student.notes = [];
@@ -344,6 +362,9 @@ export const useStudentStore = defineStore("student", {
344362
setStudentOptionalProgramsAuditHistory(payload) {
345363
this.student.auditHistoryOptionalPrograms = payload;
346364
},
365+
setStudentCourseAuditHistory(payload) {
366+
this.student.auditHistoryCourses = payload;
367+
},
347368
setStudentCareerPrograms(payload) {
348369
this.student.careerPrograms = payload;
349370
},
@@ -609,6 +630,9 @@ export const useStudentStore = defineStore("student", {
609630
getStudentOptionalProgramAuditHistory() {
610631
return this.student.auditHistoryOptionalPrograms;
611632
},
633+
getStudentCourseAuditHistory() {
634+
return this.student.auditHistoryCourses;
635+
},
612636
getAdvancedSearchProps() {
613637
return this.advancedSearchProps;
614638
},

0 commit comments

Comments
 (0)