-
-
Now
-
Scheduling
+
+
+
+
+ legend
+
+ {{ col.title }}
-
- Exam: {{ selectedExam.exam_name }}
- Writer: {{ selectedExam.examinee_name }}
- Duration: {{ `${selectedExam.exam_type.number_of_hours }HRS` }}
-
-
- Non-Exam Event
- Click and Drag to select
- a time on the calendar
-
-
- Cancel
-
-
+
@@ -51,13 +36,13 @@
import OtherBookingModal from './other-booking-modal'
import ExamInventoryModal from './exam-inventory-modal'
import moment from 'moment'
- import _ from 'lodash'
import 'fullcalendar/dist/fullcalendar.css'
import 'fullcalendar-scheduler'
+ import SchedulingIndicator from './scheduling-indicator'
export default {
name: 'Calendar',
- components: { BookingModal, DropdownCalendar, ExamInventoryModal, FullCalendar, OtherBookingModal },
+ components: { SchedulingIndicator, BookingModal, DropdownCalendar, ExamInventoryModal, FullCalendar, OtherBookingModal },
mounted() {
this.initialize()
this.$root.$on('next', () => { this.next() })
@@ -72,13 +57,9 @@
},
data() {
return {
- initialEvent: true,
- clicked: false,
- top: 80,
- left: 10,
setup: {
- unselectCancel: '.modal, .modal-content',
selectable: false,
+ unselectCancel: '.modal, .modal-content',
editable: false,
schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
showNonCurrentDates: false,
@@ -87,17 +68,18 @@
height: 'auto',
timezone: 'local',
defaultView: 'agendaWeek',
- resourceAreaWidth: 100,
views: {
- timelineDay: {
- slotWidth: 40,
- allDaySlot: false,
- },
agendaDay: {
allDaySlot: false,
+ groupByResource: true,
},
agendaWeek: {
allDaySlot: false,
+ groupByDateAndResource: true,
+ },
+ month: {
+ allDaySlot: false,
+ groupByResource: false,
},
},
resources: [],
@@ -109,15 +91,15 @@
center: null,
right: null
},
- groupByDateAndResource: false,
- groupByResource: false,
},
}
},
computed: {
- ...mapGetters(['calendar_events']),
+ ...mapGetters(['calendar_events', 'room_resources']),
...mapState([
+ 'calendarSetup',
'exams',
+ 'exam_types',
'scheduling',
'schedulingOther',
'selectedExam',
@@ -126,29 +108,37 @@
'showSchedulingIndicator',
'viewPortSizes',
]),
+ calView() {
+ if (this.calendarSetup && this.calendarSetup.viewName) {
+ return this.calendarSetup.viewName
+ }
+ return ''
+ },
+ roomLegendArray() {
+ if (this.room_resources && this.room_resources.length > 0) {
+ return this.room_resources.map(room =>
+ ({color: room.eventColor, title: room.title})
+ )
+ }
+ return []
+ },
events() {
if (this.calendar_events.length > 0) {
return this.calendar_events
}
return []
},
- indicatorStyle() {
- return {top: this.top+'px', left: this.left+'px'}
- },
},
destroyed() {
- this.setCalendarTitle(null)
+ this.setCalendarSetup(null)
},
methods: {
- ...mapActions(['getBookings', 'finishBooking', 'initializeAgenda',]),
+ ...mapActions(['getBookings', 'finishBooking', 'initializeAgenda', 'getExamTypes']),
...mapMutations([
- 'navigationVisible',
- 'setCalendarTitle',
+ 'setCalendarSetup',
'setClickedDate',
- 'setSelectedDate',
'setSelectedExam',
'toggleBookingModal',
- 'toggleCalendarControls',
'toggleOtherBookingModal',
'toggleScheduling',
'toggleSchedulingIndicator',
@@ -161,11 +151,12 @@
this.$refs.bookingcal.fireMethod('changeView', 'agendaWeek')
},
cancel() {
+ //passed to child component SchedulingIndicator as prop
this.finishBooking()
- this.unselect()
this.options({name: 'selectable', value: false})
},
initialize() {
+ this.getExamTypes()
this.initializeAgenda().then( rooms => {
rooms.forEach( room => {
let roomObj = {
@@ -175,29 +166,19 @@
}
this.$refs.bookingcal.fireMethod('addResource', roomObj)
})
- this.setupResourceView(rooms)
this.getBookings()
})
},
+ mainDivStyle() {
+ return {
+ position: 'relative'
+ }
+ },
month() {
this.$refs.bookingcal.fireMethod('changeView', 'month')
- this.$refs.bookingcal.fireMethod('option', 'groupByResource', false)
},
- moveCard(e) {
- e.preventDefault()
- if (this.clicked) {
- if (this.initialEvent === true) {
- this.offsetX = e.clientX
- this.offsetY = e.clientY
- this.initialEvent = false
- }
- let adjX = e.clientX - this.offsetX
- let adjY = e.clientY - this.offsetY
- this.offsetX = e.clientX
- this.offsetY = e.clientY
- this.left += adjX
- this.top += adjY
- }
+ goToDate(date) {
+ this.$refs.bookingcal.fireMethod('gotoDate', date)
},
next() {
this.$refs.bookingcal.fireMethod('next')
@@ -208,12 +189,12 @@
prev() {
this.$refs.bookingcal.fireMethod('prev')
},
- resetDrag(e) {
- e.preventDefault()
- this.initialEvent = true
- this.clicked = false
- },
selectEvent(event) {
+ if (this.calendarSetup.viewName === 'month') {
+ this.goToDate(event.start.local())
+ this.agendaDay()
+ return
+ }
if (this.scheduling) {
this.setClickedDate(event)
this.toggleSchedulingIndicator(false)
@@ -225,46 +206,23 @@
this.toggleOtherBookingModal(true)
}
},
- setupResourceView(rooms) {
- if (rooms.length <= 3) {
- this.options({name:'groupByDateAndResource', value: true})
- }
- if (rooms.length > 3 && rooms.length <= 5) {
- this.options({name:'groupByResource', value: true})
- }
- },
- startDrag(e) {
- e.preventDefault()
- this.initialEvent = true
- this.clicked = true
- },
today() {
this.$refs.bookingcal.fireMethod('today')
},
viewRender(view, el) {
- if (this.room_resources && this.room_resources.length > 0) {
- this.setupResourceView(this.room_resources)
- }
- this.setCalendarTitle({ title: view.title, view: view.name })
+ this.setCalendarSetup({ title: view.title, viewName: view.name })
if (view.name === 'basicDay') {
this.$refs.bookingcal.fireMethod('changeView', 'agendaDay')
}
- if (view.name === 'agendaWeek') {
- //days = refs to the text dates displayed in the column headers (ie. the day of the week and month)
- let days = el.find('th > a')
- let length = days.length
- //weeksArray is empty array with as many slots as the number of times Mon-Fri dates are rendered in header
- //eg. 5x per room_resource when groupByDateAndResource===true
- let weeksArray = Array(length / 5)
- //fill the empty slots with [1,2,3,4,5] and flaten
- //now is a template for calculating the day based on days from interval start, left to right, across headers
- _.fill(weeksArray, [1,2,3,4,5])
- let flaten = (arr) => [].concat(...arr)
- let addDaysArray = flaten(weeksArray)
- for (let i = 0; i < length; i++) {
- let header = new moment(view.intervalStart).add(addDaysArray[i], 'days')
- days[i].innerHTML = header.format(`D[/]ddd`)
+ if (view.name === 'month') {
+ let adj = 75
+ if (this.scheduling || this.schedulingOther) {
+ adj = 130
}
+ this.options({name: 'height', value: this.viewPortSizes.h - adj})
+ }
+ if (view.name === 'agendaDay' || view.name === 'agendaWeek' ) {
+ this.options({name: 'height', value: 'auto'})
}
},
unselect() {
@@ -274,20 +232,4 @@
}
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/frontend/src/booking/dropdown-calendar.vue b/frontend/src/booking/dropdown-calendar.vue
index ba1c2e1e2..a05aba8e8 100644
--- a/frontend/src/booking/dropdown-calendar.vue
+++ b/frontend/src/booking/dropdown-calendar.vue
@@ -18,10 +18,10 @@
export default {
name: "DropdownCalendar",
computed: {
- ...mapState(['calendarTitle']),
+ ...mapState(['calendarSetup']),
view() {
- if (this.calendarTitle) {
- switch (this.calendarTitle.view) {
+ if (this.calendarSetup) {
+ switch (this.calendarSetup.viewName) {
case 'agendaDay':
return 'Single Day'
case 'agendaWeek':
diff --git a/frontend/src/booking/other-booking-modal.vue b/frontend/src/booking/other-booking-modal.vue
index 589f03a1b..9a7dbe093 100644
--- a/frontend/src/booking/other-booking-modal.vue
+++ b/frontend/src/booking/other-booking-modal.vue
@@ -5,7 +5,6 @@
:no-close-on-backdrop="true"
lazy
@show="show"
- @hidden="hide"
@cancel="cancel"
@ok="postEvent"
hide-header
@@ -203,10 +202,10 @@
this.state = null
},
incrementDuration() {
- this.added -= .5
+ this.added += .5
},
decrementDuration() {
- this.added += .5
+ this.added -= .5
},
postEvent(e) {
e.preventDefault()
diff --git a/frontend/src/booking/scheduling-indicator.vue b/frontend/src/booking/scheduling-indicator.vue
new file mode 100644
index 000000000..37892dcbc
--- /dev/null
+++ b/frontend/src/booking/scheduling-indicator.vue
@@ -0,0 +1,64 @@
+
+
+
+
+ Now Scheduling
+
+
+ {{ scheduling ? 'Exam Event' : 'Non-Exam Event' }}
+
+
+ Duration: {{ selectedExam.exam_type.number_of_hours }} HRS
+
+
+ Exam: {{ selectedExam.exam_name }}
+ Expiry Date: {{ expiryDateFormat }}
+
+
+ Click and Drag to select
+ a time on the calendar
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/src/exams/add-exam-form-controller.vue b/frontend/src/exams/add-exam-form-controller.vue
index de4dde3a7..b0ff1085d 100644
--- a/frontend/src/exams/add-exam-form-controller.vue
+++ b/frontend/src/exams/add-exam-form-controller.vue
@@ -53,6 +53,7 @@
NotesQuestion,
SelectQuestion
} from './add-exam-form-components.js'
+ import moment from 'moment'
export default {
name: "AddExamFormController",
@@ -66,19 +67,12 @@
SelectQuestion
},
mounted() {
- let d = new Date()
- let month = String(d.getMonth())
- if (month.length === 1) {
- month = '0' + month
- }
- let number = String(d.getDate())
- if (number.length === 1) {
- number = '0' + number
- }
- let date = `${d.getFullYear()}-${month}-${number}`
- this.captureExamDetail({key:'exam_received_date', value: date})
- this.captureExamDetail({key:'notes', value: ''})
this.getExamTypes()
+ //assigning an empty value to notes so it gets picked up by submitter function later if not filled in by user
+ this.captureExamDetail({key:'notes', value: ''})
+ let d = new Date()
+ let today = moment(d).format('YYYY-MM-DD')
+ this.captureExamDetail({key:'exam_received_date', value: today})
},
data() {
return {
@@ -226,23 +220,6 @@
key: e.target.name,
value: e.target.value,
}
- if (this.step === 3) {
- let number, month
- let d = new Date()
- if (this.today) {
- month = String(d.getMonth())
- if (month.length === 1) {
- month = '0' + month
- }
- number = String(d.getDate())
- if (number.length === 1) {
- number = '0' + number
- }
- let date = `${d.getFullYear()}-${month}-${number}`
- payload.key = 'exam_received_date'
- payload.value = date
- }
- }
if (this.step === 1) {
payload.key = 'exam_type_id'
payload.value = e.target.id
diff --git a/frontend/src/exams/exam-inventory-table.vue b/frontend/src/exams/exam-inventory-table.vue
index 29c7f4fbf..138549688 100644
--- a/frontend/src/exams/exam-inventory-table.vue
+++ b/frontend/src/exams/exam-inventory-table.vue
@@ -1,5 +1,5 @@
-
+
@@ -10,7 +10,7 @@
-
{{ row.item.exam_received === 0 ? 'No' : 'Yes' }}
+
+ {{ getInvigilator(row) }}
+
{{ row.item.expiry_date.split('T')[0] }}
@@ -40,6 +43,7 @@
data() {
return {
filter: null,
+ events: null,
fields: [
{key: 'office.office_name', label: 'Office', sortable: true},
{key: 'event_id', label: 'Event ID', sortable: false },
@@ -49,13 +53,13 @@
{key: 'exam_received', label: 'Received?', sortable: true },
{key: 'examinee_name', label: 'Student Name', sortable: true },
{key: 'notes', label: 'Notes', sortable: false },
- {key: 'invigilator.invigilator_name', label: 'Invigilator', sortable: true },
+ {key: 'invigilator', label: 'Invigilator', sortable: true },
{key: 'booking.room.room_name', label: 'Location', sortable: true },
],
}
},
methods: {
- ...mapActions(['getExams']),
+ ...mapActions(['getExams', 'getBookings']),
...mapMutations([
'navigationVisible',
'setSelectedExam',
@@ -64,6 +68,16 @@
'toggleScheduling',
'toggleSchedulingIndicator',
]),
+ getInvigilator(row) {
+ if (this.events) {
+ let bookingObj = this.events.find(event=>event.booking_id==row.item.booking_id)
+ if (bookingObj && bookingObj.invigilator) {
+ return bookingObj.invigilator.invigilator_name
+ }
+ return ''
+ }
+ return ''
+ },
clickRow(e) {
if (this.showExamInventoryModal) {
this.$root.$emit('options', {name: 'selectable', value: true})
@@ -77,16 +91,19 @@
},
},
mounted() {
+ this.getBookings().then(bookings => {
+ this.events = bookings
+ })
this.getExams()
},
computed: {
- ...mapGetters(['role_code', 'exam_inventory']),
- ...mapState(['user', 'showExamInventoryModal']),
- exams() {
- if (this.exam_inventory && Array.isArray(this.exam_inventory)) {
+ ...mapGetters(['role_code', 'exam_inventory', 'calendar_events']),
+ ...mapState(['user', 'exams', 'showExamInventoryModal', 'bookings']),
+ selectedExams() {
+ if (this.showExamInventoryModal) {
return this.exam_inventory
}
- return []
+ return this.exams
},
getFields() {
if (this.role_code === "LIAISON") {
diff --git a/frontend/src/layout/footer.vue b/frontend/src/layout/footer.vue
index b741f9531..eb997a2fc 100644
--- a/frontend/src/layout/footer.vue
+++ b/frontend/src/layout/footer.vue
@@ -58,6 +58,7 @@
border-top: 2px solid #fcba19;
font-size: .850rem;
font-family: Myriad-Pro, Calibri, Arial, sans serif;
+ z-index:1000;
}
#footer-links {
padding-left: 10px;
diff --git a/frontend/src/layout/nav.vue b/frontend/src/layout/nav.vue
index 5cbd37385..e8113241c 100644
--- a/frontend/src/layout/nav.vue
+++ b/frontend/src/layout/nav.vue
@@ -15,13 +15,13 @@
-->
-
+
The Q
- Branch Agenda
Room Booking
- Manage Exams
+ Exam Admin
+ Office Agenda
-
@@ -67,11 +67,21 @@