diff --git a/frontend/src/components/Admin/InstituteAlerts.vue b/frontend/src/components/Admin/InstituteAlerts.vue index 82f47fc4..99b2bad5 100644 --- a/frontend/src/components/Admin/InstituteAlerts.vue +++ b/frontend/src/components/Admin/InstituteAlerts.vue @@ -1,5 +1,18 @@ - - - @@ -108,55 +100,13 @@ export default { { key: "createDate", title: "Create Date", sortable: false }, { key: "event.eventType", title: "Alert Event Type", sortable: false }, { key: "subject", title: "Subject", sortable: false }, - { key: "acknowledgeFlag", title: "Acknowledge", sortable: false }, { key: "updateUser", title: "IDIR", sortable: false }, { key: "updateDate", title: "Acknowledge Date", sortable: false }, - { key: "actions", title: "Actions", sortable: false }, - ], - // these should align with events defined in TRAX API: - // https://github.com/bcgov/EDUC-GRAD-TRAX-API/blob/main/api/src/main/java/ca/bc/gov/educ/api/trax/constant/EventType.java - instituteEvents: [ - { key: "UPDATE_SCHOOL", description: "Update School" }, - { key: "CREATE_SCHOOL", description: "New School" }, - { key: "UPDATE_DISTRICT", description: "Update District" }, - { key: "CREATE_DISTRICT", description: "Create District" }, - { key: "UPDATE_AUTHORITY", description: "Update Authority" }, - { key: "CREATE_AUTHORITY", description: "Create Authority" }, - { key: "GET_AUTHORITY", description: "Get Authority" }, - { key: "GET_PAGINATED_SCHOOLS", description: "Get Paginated Schools" }, - { - key: "GET_PAGINATED_AUTHORITIES", - description: "Get Paginated Authorities", - }, - { key: "MOVE_SCHOOL", description: "Move School" }, - { key: "CREATE_SCHOOL_CONTACT", description: "Create School Contact" }, - { key: "UPDATE_SCHOOL_CONTACT", description: "Update School Contact" }, - { key: "DELETE_SCHOOL_CONTACT", description: "Delete School Contact" }, - { - key: "CREATE_DISTRICT_CONTACT", - description: "Create District Contact", - }, - { - key: "UPDATE_DISTRICT_CONTACT", - description: "Update District Contact", - }, - { - key: "DELETE_DISTRICT_CONTACT", - description: "Delete District Contact", - }, - { - key: "CREATE_AUTHORITY_CONTACT", - description: "Create Authority Contact", - }, - { - key: "UPDATE_AUTHORITY_CONTACT", - description: "Update Authority Contact", - }, - { - key: "DELETE_AUTHORITY_CONTACT", - description: "Delete Authority Contact", - }, + { key: "actions", title: "Acknowledge", sortable: false }, ], + filterOptions: { + acknowledgeFlag: "N", + }, }; }, created() { @@ -178,10 +128,6 @@ export default { isSchoolActivity(activity) { return activity.event.eventType.includes("SCHOOL"); }, - getInstituteEventLabel(key) { - return this.instituteEvents.find((event) => key === event.key) - ?.description; - }, getPassthroughURL(activity) { if (this.isDistrictActivity(activity)) { return `${ @@ -208,11 +154,31 @@ export default { this.currentPage = page; this.getInstituteAlerts(); }, + // TODO: Review this when we implement batch filtering in GRAD2-2553 getInstituteAlerts: function () { this.loadingTable = true; - let params = `pageNumber=${this.currentPage - 1}&pageSize=${ - this.itemsPerPage - }`; + let params = { + pageNumber: this.currentPage - 1, + pageSize: this.itemsPerPage, + sort: { + createDate: "DEC", + }, + searchParams: [], + }; + if (this.filterOptions.acknowledgeFlag !== "All") { + params.searchParams.push({ + condition: null, + searchCriteriaList: [ + { + key: "acknowledgeFlag", + operation: "eq", + value: this.filterOptions.acknowledgeFlag, + valueType: "STRING", + condition: null, + }, + ], + }); + } // update to pass in page, itemsPerPage, and sortBy TRAXService.getInstituteEventHistory(params) .then((response) => { diff --git a/frontend/src/components/Batch/Forms/ArchiveSchoolReportsForm.vue b/frontend/src/components/Batch/Forms/ArchiveSchoolReportsForm.vue index 3ce72966..48ace36c 100644 --- a/frontend/src/components/Batch/Forms/ArchiveSchoolReportsForm.vue +++ b/frontend/src/components/Batch/Forms/ArchiveSchoolReportsForm.vue @@ -344,6 +344,8 @@ export default { this.dialog = false; this.clearBatchDetails(); this.step = 0; + this.selectedConfirmations = []; + this.reportType = null; }, cancel() { this.group = null; diff --git a/frontend/src/components/Batch/Forms/ArchiveStudentsForm.vue b/frontend/src/components/Batch/Forms/ArchiveStudentsForm.vue index eb133fbf..05e8192d 100644 --- a/frontend/src/components/Batch/Forms/ArchiveStudentsForm.vue +++ b/frontend/src/components/Batch/Forms/ArchiveStudentsForm.vue @@ -351,6 +351,7 @@ export default { this.dialog = false; this.clearBatchDetails(); this.step = 0; + this.selectedConfirmations = []; }, cancel() { this.group = null; diff --git a/frontend/src/components/Batch/Forms/DistrunFormYearEndForm.vue b/frontend/src/components/Batch/Forms/DistrunFormYearEndForm.vue index ca7119d0..7cca2db7 100644 --- a/frontend/src/components/Batch/Forms/DistrunFormYearEndForm.vue +++ b/frontend/src/components/Batch/Forms/DistrunFormYearEndForm.vue @@ -15,7 +15,7 @@
-End Credentials and Transcript DistrYearibution RunYear-End Credentials and Transcript Distribution Run ({ + snackbarStore: useSnackbarStore(), step: 0, batchLoading: false, dialog: false, + snackbarStore: useSnackbarStore(), }), computed: { ...mapState(useAccessStore, ["hasPermissions"]), diff --git a/frontend/src/components/Batch/Forms/FormInputs/DistrictInput.vue b/frontend/src/components/Batch/Forms/FormInputs/DistrictInput.vue index a3012276..44e14d97 100644 --- a/frontend/src/components/Batch/Forms/FormInputs/DistrictInput.vue +++ b/frontend/src/components/Batch/Forms/FormInputs/DistrictInput.vue @@ -43,7 +43,7 @@ v-model="district" v-if="!selectAllDistricts" :items="getDistrictList" - label="Category" + label="District" variant="outlined" :item-title="districtTitle" item-value="districtNumber" diff --git a/frontend/src/components/Batch/Forms/FormInputs/ScheduleInput.vue b/frontend/src/components/Batch/Forms/FormInputs/ScheduleInput.vue index 355640d9..42b2a825 100644 --- a/frontend/src/components/Batch/Forms/FormInputs/ScheduleInput.vue +++ b/frontend/src/components/Batch/Forms/FormInputs/ScheduleInput.vue @@ -60,7 +60,7 @@ hide-default-header hide-default-footer >
diff --git a/frontend/src/components/Batch/Forms/FormInputs/SchoolInput.vue b/frontend/src/components/Batch/Forms/FormInputs/SchoolInput.vue index 2afd8b4e..874c108c 100644 --- a/frontend/src/components/Batch/Forms/FormInputs/SchoolInput.vue +++ b/frontend/src/components/Batch/Forms/FormInputs/SchoolInput.vue @@ -28,6 +28,23 @@ + + {{ validationMessage @@ -83,6 +100,7 @@ import SchoolService from "@/services/SchoolService.js"; import StudentService from "@/services/StudentService.js"; import GraduationReportService from "@/services/GraduationReportService.js"; import DateRangeInput from "./DateRangeInput.vue"; +import OpenStatusBadge from "@/components/Common/OpenStatusBadge.vue"; import { useVuelidate } from "@vuelidate/core"; import { useBatchRequestFormStore } from "../../../../store/modules/batchRequestFormStore"; import { useAppStore } from "../../../../store/modules/app"; @@ -90,7 +108,10 @@ import { mapActions, mapState } from "pinia"; import { required, minLength, helpers } from "@vuelidate/validators"; export default { - components: { DateRangeInput: DateRangeInput }, + components: { + DateRangeInput: DateRangeInput, + OpenStatusBadge: OpenStatusBadge, + }, setup() { const batchRequestFormStore = useBatchRequestFormStore(); const gradDateFrom = ref(batchRequestFormStore.gradDateFrom); @@ -217,7 +238,11 @@ export default { }, computed: { - ...mapState(useAppStore, ["getSchoolsList", "getSchoolById", "displaySchoolCategoryCode"]), + ...mapState(useAppStore, [ + "getSchoolsList", + "getSchoolById", + "displaySchoolCategoryCode", + ]), isEmpty() { return this.students.length > 0; }, diff --git a/frontend/src/components/Batch/Forms/FormInputs/StudentInput.vue b/frontend/src/components/Batch/Forms/FormInputs/StudentInput.vue index 5b62b310..7d33ec76 100644 --- a/frontend/src/components/Batch/Forms/FormInputs/StudentInput.vue +++ b/frontend/src/components/Batch/Forms/FormInputs/StudentInput.vue @@ -183,8 +183,12 @@ export default { lastName: student.data[0].legalLastName, dob: student.data[0].dob, status: studentGRADStatus.data.studentStatusName, - schoolOfRecord: this.getSchoolById(studentGRADStatus.data.schoolOfRecordId)?.displayName, - schoolAtGrad: this.getSchoolById(studentGRADStatus.data.schoolAtGradId)?.displayName, + schoolOfRecord: this.getSchoolById( + studentGRADStatus.data.schoolOfRecordId + )?.displayName, + schoolAtGrad: this.getSchoolById( + studentGRADStatus.data.schoolAtGradId + )?.displayName, program: studentGRADStatus.data.program, }; if (studentGRADStatus.data.studentStatusName == "Merged") { @@ -193,6 +197,7 @@ export default { this.penLoading = false; return; } + // validation fot students on the CERT_REGEN batch job if (this.runType == "CERT_REGEN") { //when User is entereing PENs for the REGEN process, error if the student has a null PROGRAM COMPLETION DATE if (!studentGRADStatus.data.programCompletionDate) { @@ -201,6 +206,12 @@ export default { this.penLoading = false; return; } + if (student.data[0]?.certificateEligibility == "N") { + this.validationMessage = + "This students' school at graduation is not eligible for certificates"; + this.penLoading = false; + return; + } } //check if what credentialType was selected @@ -250,13 +261,13 @@ export default { computed: { ...mapState(useBatchRequestFormStore, [ - "getBatchRequest", - "getBatchRunTime", - "getCredential", - ]), + "getBatchRequest", + "getBatchRunTime", + "getCredential", + ]), ...mapState(useAppStore, { - getSchoolById: "getSchoolById" - }), + getSchoolById: "getSchoolById", + }), isEmpty() { return this.students.length > 0; }, diff --git a/frontend/src/components/Batch/Forms/NongradDistrunForm.vue b/frontend/src/components/Batch/Forms/NongradDistrunForm.vue index 92c6449b..48afeb63 100644 --- a/frontend/src/components/Batch/Forms/NongradDistrunForm.vue +++ b/frontend/src/components/Batch/Forms/NongradDistrunForm.vue @@ -61,12 +61,7 @@ > - + diff --git a/frontend/src/components/Batch/Forms/RegenerateSchoolReportForm.vue b/frontend/src/components/Batch/Forms/RegenerateSchoolReportForm.vue index d0c9f4c0..5fb9b30e 100644 --- a/frontend/src/components/Batch/Forms/RegenerateSchoolReportForm.vue +++ b/frontend/src/components/Batch/Forms/RegenerateSchoolReportForm.vue @@ -285,6 +285,7 @@ export default { this.dialog = false; this.clearBatchDetails(); this.step = 0; + this.reportType = null; }, cancel() { this.group = null; diff --git a/frontend/src/components/Common/OpenStatusBadge.vue b/frontend/src/components/Common/OpenStatusBadge.vue index bbd8c500..3b5ec919 100644 --- a/frontend/src/components/Common/OpenStatusBadge.vue +++ b/frontend/src/components/Common/OpenStatusBadge.vue @@ -1,12 +1,52 @@ diff --git a/frontend/src/components/Common/SchoolDetailsDialog.vue b/frontend/src/components/Common/SchoolDetailsDialog.vue index abe8f17a..8709b553 100644 --- a/frontend/src/components/Common/SchoolDetailsDialog.vue +++ b/frontend/src/components/Common/SchoolDetailsDialog.vue @@ -1,14 +1,14 @@ - + diff --git a/frontend/src/components/SchoolReports/SchoolReports.vue b/frontend/src/components/SchoolReports/SchoolReports.vue index 4081be77..150c85bd 100644 --- a/frontend/src/components/SchoolReports/SchoolReports.vue +++ b/frontend/src/components/SchoolReports/SchoolReports.vue @@ -3,25 +3,46 @@
-
-
- - -
+
+
+ + + +
-
+
+
- Search - + + > Reset - -
+
+
-
+
-
+
- - + \ No newline at end of file + diff --git a/frontend/src/components/StudentProfile/GraduationStatus/GRADStatusForm.vue b/frontend/src/components/StudentProfile/GraduationStatus/GRADStatusForm.vue index a3a108db..7245c6f6 100644 --- a/frontend/src/components/StudentProfile/GraduationStatus/GRADStatusForm.vue +++ b/frontend/src/components/StudentProfile/GraduationStatus/GRADStatusForm.vue @@ -374,6 +374,32 @@ + + + + @@ -441,7 +467,7 @@ .ifSchoolAtGradIdProgramIs1950AndOffshore.$message }}
- {{ label.label }} - + --> +

+ {{ + getSchoolById(editedGradStatus?.schoolAtGradId)?.mincode + }} + - + {{ + getSchoolById(editedGradStatus?.schoolAtGradId) + ?.displayName + }} +

@@ -638,11 +676,16 @@ import { parseStudentStatus, } from "../../../utils/common.js"; +import OpenStatusBadge from "@/components/Common/OpenStatusBadge.vue"; + import sharedMethods from "../../../sharedMethods"; import StudentService from "@/services/StudentService.js"; import InstituteService from "@/services/InstituteService.js"; export default { name: "GRADStatusForm", + components: { + OpenStatusBadge: OpenStatusBadge, + }, created() { this.containsAnyLetters = containsAnyLetters; this.parseStudentStatus = parseStudentStatus; diff --git a/frontend/src/main.js b/frontend/src/main.js index 292cb164..3723386f 100644 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -18,6 +18,8 @@ import Snackbar from "./components/Common/Snackbar.vue"; import "./assets/css/bcgov.css"; import "./assets/css/global.css"; +// test comment + //define custom theme const bcGovTheme = { dark: false, diff --git a/frontend/src/services/TRAXService.js b/frontend/src/services/TRAXService.js index b04feb5d..7229f605 100644 --- a/frontend/src/services/TRAXService.js +++ b/frontend/src/services/TRAXService.js @@ -7,12 +7,15 @@ export default { getDistrict(district) { return ApiService.apiAxios.get("/api/v1/trax/district/" + district); }, - // Note: Sort is currently hard coded in the URL, however we'll want to update this when we tackle sorting & filtering in a future ticket + // TODO: Review this when we implement batch filtering in GRAD2-2553 getInstituteEventHistory(params) { + const encodedSortParams = encodeURIComponent(JSON.stringify(params.sort)); + const encodedSearchParams = encodeURIComponent( + JSON.stringify(params.searchParams) + ); + console.log(params.pageSize); return ApiService.apiAxios.get( - "/api/v1/trax/event/history/paginated?" + - params + - "&sort=%7B%22createDate%22%3A%22DEC%22%7D" + `/api/v1/trax/event/history/paginated?pageNumber=${params.pageNumber}&pageSize=${params.pageSize}&sort=${encodedSortParams}&searchParams=${encodedSearchParams}` ); }, putInstituteEventHistory(json) { diff --git a/frontend/src/sharedMethods.js b/frontend/src/sharedMethods.js index a235ba6a..123dc2e5 100644 --- a/frontend/src/sharedMethods.js +++ b/frontend/src/sharedMethods.js @@ -134,34 +134,92 @@ export default { }, sortDistrictListByActiveAndDistrictNumber(districtsList) { if (!districtsList) return []; - + return districtsList.sort((a, b) => { // First, prioritize districts with districtStatusCode "ACTIVE" - if (a.districtStatusCode === "ACTIVE" && b.districtStatusCode !== "ACTIVE") { + if ( + a.districtStatusCode === "ACTIVE" && + b.districtStatusCode !== "ACTIVE" + ) { return -1; // "ACTIVE" comes first } - if (a.districtStatusCode !== "ACTIVE" && b.districtStatusCode === "ACTIVE") { + if ( + a.districtStatusCode !== "ACTIVE" && + b.districtStatusCode === "ACTIVE" + ) { return 1; // "ACTIVE" comes first } - + // Second, sort by districtNumber (as numeric, handling strings like "103", "005", etc.) const aNumber = parseInt(a.districtNumber, 10); const bNumber = parseInt(b.districtNumber, 10); - + return aNumber - bNumber; // Numeric sorting }); }, - sortSchoolListByTranscriptsAndMincode(schoolsList) { - if (!schoolsList) return []; + getSchoolOpenStatus(openedDateString, closedDateString) { + const openedDate = new Date(openedDateString); + const closedDate = !!closedDateString ? new Date(closedDateString) : null; + const currentDate = new Date(); + if (openedDate <= currentDate && !closedDate) { + return "Open"; + } else if ( + openedDate <= currentDate && + closedDate && + currentDate < closedDate + ) { + return "Closing"; + } else if (currentDate < openedDate) { + return "Opening"; + } else if (closedDate && closedDate < currentDate) { + return "Closed"; + } else { + return "Invalid"; //return Invalid in case of bad data to sort at bottom of list + } + }, + sortSchoolList(schoolsList) { + if (!schoolsList) return []; return [...schoolsList].sort((a, b) => { - // Sort by canIssueCertificates first (descending - true values first) + // Sort by canIssueTranscript first (descending - true values first) if (a.canIssueTranscripts && !b.canIssueTranscripts) { return -1; } else if (!a.canIssueTranscripts && b.canIssueTranscripts) { return 1; } - // If canIssueTranscripts is the same, sort by mincode (ascending) + + // Sort by canIssueCertificates first (descending - true values first) + if (a.canIssueCertificates && !b.canIssueCertificates) { + return -1; + } else if (!a.canIssueCertificates && b.canIssueCertificates) { + return 1; + } + + // Sort by school status (descending: open - closing - opening - closed) + const openStatusOrder = { + Open: 0, + Closing: 1, + Opening: 2, + Closed: 3, + Invalid: 4, + }; + if ( + openStatusOrder[ + this.getSchoolOpenStatus(a?.openedDate, a?.closedDate) + ] < + openStatusOrder[this.getSchoolOpenStatus(b?.openedDate, b?.closedDate)] + ) { + return -1; + } else if ( + openStatusOrder[ + this.getSchoolOpenStatus(a?.openedDate, a?.closedDate) + ] > + openStatusOrder[this.getSchoolOpenStatus(b?.openedDate, b?.closedDate)] + ) { + return 1; + } + + // If they all are the same, sort by mincode (ascending) return a.mincode.localeCompare(b.mincode); }); }, diff --git a/frontend/src/store/modules/app.js b/frontend/src/store/modules/app.js index ace100d8..36bf487a 100644 --- a/frontend/src/store/modules/app.js +++ b/frontend/src/store/modules/app.js @@ -150,10 +150,7 @@ export const useAppStore = defineStore("app", { InstituteService.getSchoolsList().then((response) => { try { this.schoolsList = response.data; - this.schoolsList = - sharedMethods.sortSchoolListByTranscriptsAndMincode( - this.schoolsList - ); + this.schoolsList = sharedMethods.sortSchoolList(this.schoolsList); } catch (error) { console.error(error); }