-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First commit for tasks: EAC-8 & EAC-12.
- Loading branch information
1 parent
b75eb8c
commit c89a691
Showing
14 changed files
with
564 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
'use strict'; | ||
const { logApiError, getData, errorResponse } = require('../utils'); | ||
const HttpStatus = require('http-status-codes'); | ||
const utils = require('../utils'); | ||
|
||
const config = require('../../config'); | ||
|
||
async function getAssessmentSessions(req, res) { | ||
try { | ||
const url = `${config.get('server:eas:assessmentSessionsURL')}`; | ||
const data = await getData(url); | ||
return res.status(200).json(data); | ||
} catch (e) { | ||
logApiError(e, 'getAssessmentSessions', 'Error occurred while attempting to GET assessment sessions.'); | ||
return errorResponse(res); | ||
} | ||
} | ||
|
||
async function updateAssessmentSession(req, res) { | ||
if (req.params.assessmentSessionID !== req.body.assessmentSessionID) { | ||
return res.status(HttpStatus.BAD_REQUEST).json({ | ||
message: 'The assessmentSessionID in the URL didn\'t match the assessmentSessionID in the request body.' | ||
}); | ||
} | ||
try { | ||
const userInfo = utils.getUser(req); | ||
const payload = { | ||
assessmentSessionID: req.body.assessmentSessionID, | ||
activeFromDate: req.body.activeFromDate, | ||
activeUntilDate: req.body.activeUntilDate, | ||
updateUser: userInfo.idir_username | ||
}; | ||
const result = await utils.putData(`${config.get('server:eas:assessmentSessionsURL')}/${req.body.assessmentSessionID}`, payload, utils.getUser(req).idir_username); | ||
return res.status(HttpStatus.OK).json(result); | ||
} catch (e) { | ||
logApiError(e, 'updateAssessmentSession', 'Error occurred while attempting to save the changes to the assessment session.'); | ||
return errorResponse(res); | ||
} | ||
} | ||
module.exports = { | ||
getAssessmentSessions, | ||
updateAssessmentSession | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
const passport = require('passport'); | ||
const express = require('express'); | ||
const router = express.Router(); | ||
const { getAssessmentSessions, updateAssessmentSession } = require('../components/eas/eas'); | ||
const utils = require('../components/utils'); | ||
const extendSession = utils.extendSession(); | ||
const permUtils = require('../components/permissionUtils'); | ||
const perm = require('../util/Permission'); | ||
|
||
const PERMISSION = perm.PERMISSION; | ||
|
||
router.get('/assessment-sessions', passport.authenticate('jwt', {session: false}, undefined), permUtils.checkUserHasPermission(PERMISSION.MANAGE_EAS_SESSIONS_PERMISSION), extendSession, getAssessmentSessions); | ||
router.put('/assessment-sessions/:assessmentSessionID', passport.authenticate('jwt', {session: false}, undefined), permUtils.checkUserHasPermission(PERMISSION.MANAGE_EAS_SESSIONS_PERMISSION), extendSession, updateAssessmentSession); | ||
|
||
module.exports = router; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
171 changes: 171 additions & 0 deletions
171
frontend/src/components/assessments/AssessmentSessions.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
<template> | ||
<v-container class="containerSetup mb-5"> | ||
<v-row class="pr-4"> | ||
<v-col class="pb-0 mt-4"> | ||
<h2>Open Assessment Sessions</h2> | ||
</v-col> | ||
</v-row> | ||
<v-row | ||
v-for="(sessions, index) in activeSessions" | ||
:key="index" | ||
> | ||
<v-col | ||
v-for="session in sessions" | ||
:key="session.sessionid" | ||
cols="5" | ||
> | ||
<SessionCard | ||
:session="session" | ||
:handle-open-editor="() => openEditSessionSheet(session)" | ||
/> | ||
</v-col> | ||
</v-row> | ||
<v-divider class="py-6 mt-6" /> | ||
<v-row> | ||
<v-icon icon="mdi-history pt-3" /> | ||
<h2 class="pl-2">Assessment Session History</h2> | ||
</v-row> | ||
<v-row> | ||
<v-data-table | ||
id="session-history-dataTable" | ||
v-model:items-per-page="itemsPerPage" | ||
:page="pageNumber" | ||
:items="historicalSessions" | ||
:items-length="historicalSessions?.length" | ||
:search="search" | ||
:headers="headers" | ||
:hover="true" | ||
class="fill-height" | ||
style="border-radius: 0" | ||
> | ||
<template #top> | ||
<v-text-field | ||
v-model="search" | ||
clearable | ||
hide-details="auto" | ||
label="Search" | ||
class="pa-4" | ||
/> | ||
</template> | ||
</v-data-table> | ||
</v-row> | ||
<v-dialog | ||
v-model="editSessionSheet" | ||
:inset="true" | ||
:no-click-animation="true" | ||
:scrollable="true" | ||
:persistent="true" | ||
max-width="40%" | ||
min-height="35%" | ||
> | ||
<EditSession | ||
v-if="editSessionSheet" | ||
:session="editSession" | ||
:on-success-handler="sessionEditSuccess" | ||
:close-handler="() => (editSessionSheet = false)" | ||
/> | ||
</v-dialog> | ||
</v-container> | ||
</template> | ||
|
||
<script> | ||
import SessionCard from './sessions/SessionCard.vue'; | ||
import EditSession from './sessions/SessionEdit.vue'; | ||
import ApiService from '../../common/apiService'; | ||
import { Routes } from '../../utils/constants'; | ||
import { LocalDate } from '@js-joda/core'; | ||
import moment from 'moment'; | ||
export default { | ||
name: 'AssessmentSessions', | ||
components: { | ||
SessionCard, | ||
EditSession, | ||
}, | ||
data() { | ||
return { | ||
search: null, | ||
currentYear: LocalDate.now().year(), | ||
itemsPerPage: 5, | ||
pageNumber: 1, | ||
allsessions: [], | ||
headers: [ | ||
{ title: 'Session ID', key: 'courseSession' }, | ||
{ title: 'Month', key: 'courseMonth' }, | ||
{ title: 'Year', key: 'courseYear' }, | ||
{ title: 'Open Date', key: 'activeFromDate' }, | ||
{ title: 'Close Date', key: 'activeUntilDate' }, | ||
], | ||
editSessionSheet: false, | ||
editSession: null, | ||
headerSearchParams: {}, | ||
headerSortParams: {}, | ||
}; | ||
}, | ||
computed: { | ||
activeSessions() { | ||
const orderedSessions = []; | ||
const allsessions = this.allsessions | ||
.filter((session) => session.status === 'OPEN') | ||
.map((session) => { | ||
return { | ||
...session, | ||
courseMonth: this.formatMonth(session.courseMonth) | ||
}; | ||
}); | ||
allsessions.sort((a, b) => a.courseSession - b.courseSession); | ||
for (let i = 0; i < allsessions.length; i += 2) { | ||
orderedSessions.push(allsessions.slice(i, i + 2)); | ||
} | ||
return orderedSessions; | ||
}, | ||
historicalSessions() { | ||
return this.allsessions | ||
.filter((session) => session.status !== 'OPEN') | ||
.map((session) => { | ||
return { | ||
...session, | ||
activeFromDate: this.formattoDate(session.activeFromDate), | ||
activeUntilDate: this.formattoDate(session.activeUntilDate), | ||
courseMonth: this.formatMonth(session.courseMonth), | ||
}; | ||
}); | ||
}, | ||
sessionHeaderSlotName() { | ||
return `column.${this.sessionid}`; | ||
}, | ||
}, | ||
created() { | ||
this.getAllAssessmentSessions(); | ||
}, | ||
methods: { | ||
getAllAssessmentSessions() { | ||
this.loading = true; | ||
ApiService.apiAxios | ||
.get(`${Routes.eas.GET_ASSESSMENT_SESSIONS}`, {}) | ||
.then((response) => { | ||
this.allsessions = response.data; | ||
}) | ||
.catch((error) => { | ||
console.error(error); | ||
}) | ||
.finally(() => { | ||
this.loading = false; | ||
}); | ||
}, | ||
sessionEditSuccess() { | ||
this.getAllAssessmentSessions(); | ||
}, | ||
openEditSessionSheet(session) { | ||
this.editSession = session; | ||
this.editSessionSheet = !this.editSessionSheet; | ||
}, | ||
formattoDate(date) { | ||
return moment(JSON.stringify(date), 'YYYY-MM-DDTHH:mm:ss').format('YYYY/MM/DD'); | ||
}, | ||
formatMonth(month) { | ||
return moment(month, 'MM').format('MMMM'); | ||
} | ||
}, | ||
}; | ||
</script> |
97 changes: 97 additions & 0 deletions
97
frontend/src/components/assessments/sessions/SessionCard.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
<template> | ||
<v-card | ||
:id="`sessioncard-${session.sessionid}`" | ||
fluid | ||
class="d-flex flex-column mt-4" | ||
height="100%" | ||
> | ||
<v-card-title class="text-wrap pb-0" > | ||
<v-row no-gutters class="pr-4"> | ||
<v-col> | ||
<strong class="sessionName"> {{ session.courseMonth }} {{ session.courseYear }} Session </strong> | ||
</v-col> | ||
<v-col cols="1" style="float:right;"> | ||
<a class="ml-2" @click="handleOpenEditor"> | ||
<v-icon | ||
class="edit-session-small" | ||
color="#1A5A96" | ||
:icon="'mdi-pencil'" | ||
/> | ||
</a> | ||
</v-col> | ||
</v-row> | ||
</v-card-title> | ||
<v-card-text class="mt-2 ml-2 mr-2"> | ||
<v-list class="pt-0"> | ||
<v-list-item min-height="inherit" class="pl-0"> | ||
<v-row class="dates"> | ||
<v-col cols="8"> | ||
<v-icon small class="mr-1">mdi-calendar</v-icon> | ||
<span id="opendatelabel">Registration Open Date:</span> | ||
</v-col> | ||
|
||
<v-col cols="4"> | ||
<span id="opendate"> | ||
{{ formattoDate(session.activeFromDate) }} | ||
</span> | ||
</v-col> | ||
</v-row> | ||
</v-list-item> | ||
<v-list-item min-height="inherit" class="pl-0"> | ||
<v-row> | ||
<v-col cols="8"> | ||
<v-icon small class="mr-1">mdi-calendar</v-icon> | ||
<span id="closedatelabel">Registration Close Date:</span> | ||
</v-col> | ||
<v-col cols="4"> | ||
<span id="closedate"> | ||
{{ formattoDate(session.activeUntilDate) }} | ||
</span> | ||
</v-col> | ||
</v-row> | ||
</v-list-item> | ||
</v-list> | ||
</v-card-text> | ||
<v-spacer /> | ||
</v-card> | ||
</template> | ||
|
||
<script> | ||
import moment from 'moment'; | ||
export default { | ||
name: 'SessionCard', | ||
props: { | ||
session: { | ||
type: Object, | ||
required: true, | ||
}, | ||
handleOpenEditor: { | ||
type: Function, | ||
required: true, | ||
}, | ||
}, | ||
methods: { | ||
formattoDate(date) { | ||
return moment(JSON.stringify(date), 'YYYY-MM-DDTHH:mm:ss').format('YYYY/MM/DD'); | ||
}, | ||
}, | ||
}; | ||
</script> | ||
|
||
<style scoped> | ||
.dateSubText { | ||
font-style: italic; | ||
font-size: 0.95em; | ||
} | ||
.sessionName { | ||
font-size: 1em; | ||
} | ||
.edit-session-small { | ||
font-size: 25px; | ||
margin-top: -5px; | ||
float: right; | ||
} | ||
</style> |
Oops, something went wrong.