Group session data can now be submitted and shows in session log
This commit is contained in:
parent
db00996beb
commit
6f7e5596c3
@ -33,8 +33,8 @@ data class GroupObservationInit(
|
|||||||
)
|
)
|
||||||
|
|
||||||
data class GroupObservation(
|
data class GroupObservation(
|
||||||
val scenarios: List<Scenario>,
|
val person: String,
|
||||||
val person: String
|
val scenarios: List<Scenario>
|
||||||
)
|
)
|
||||||
|
|
||||||
data class ObservationsRequest(
|
data class ObservationsRequest(
|
||||||
|
@ -2,8 +2,6 @@ package uk.co.neviyn.observationdatabase
|
|||||||
|
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
|
||||||
import org.springframework.messaging.simp.SimpMessagingTemplate
|
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import java.util.concurrent.ThreadLocalRandom
|
import java.util.concurrent.ThreadLocalRandom
|
||||||
|
|
||||||
@ -12,12 +10,9 @@ object GroupSessionManager {
|
|||||||
|
|
||||||
private val logger: Logger = LoggerFactory.getLogger(javaClass)!!
|
private val logger: Logger = LoggerFactory.getLogger(javaClass)!!
|
||||||
|
|
||||||
@Autowired
|
|
||||||
lateinit var websocketMessenger: SimpMessagingTemplate
|
|
||||||
|
|
||||||
var sessionId = ThreadLocalRandom.current().nextInt(1000, 9999)
|
var sessionId = ThreadLocalRandom.current().nextInt(1000, 9999)
|
||||||
var site: Site? = null
|
var site: Site? = null
|
||||||
var tutors: Set<Tutor>? = null
|
var tutors: List<Long>? = null
|
||||||
var trainingType: TrainingType? = null
|
var trainingType: TrainingType? = null
|
||||||
var scenarioTitles: List<String>? = null
|
var scenarioTitles: List<String>? = null
|
||||||
var observations: MutableList<Observation> = mutableListOf()
|
var observations: MutableList<Observation> = mutableListOf()
|
||||||
@ -31,7 +26,7 @@ object GroupSessionManager {
|
|||||||
}
|
}
|
||||||
logger.debug("New ID is $sessionId")
|
logger.debug("New ID is $sessionId")
|
||||||
this.site = site
|
this.site = site
|
||||||
this.tutors = tutors
|
this.tutors = tutors.map { it.id }
|
||||||
this.trainingType = trainingType
|
this.trainingType = trainingType
|
||||||
this.scenarioTitles = scenarioTitles
|
this.scenarioTitles = scenarioTitles
|
||||||
observations = mutableListOf()
|
observations = mutableListOf()
|
||||||
@ -49,14 +44,5 @@ object GroupSessionManager {
|
|||||||
|
|
||||||
fun addObservation(observation: Observation) {
|
fun addObservation(observation: Observation) {
|
||||||
observations.add(observation)
|
observations.add(observation)
|
||||||
sendObservationsToSocket()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun sendObservationsToSocket() {
|
|
||||||
if (::websocketMessenger.isInitialized) {
|
|
||||||
websocketMessenger.convertAndSend("/ws/observations", mapOf("observations" to observations))
|
|
||||||
} else {
|
|
||||||
logger.warn("WebSocket messenger is not initialized. Not sending data to socket.")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,6 +6,7 @@ import org.slf4j.LoggerFactory
|
|||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.core.env.Environment
|
import org.springframework.core.env.Environment
|
||||||
import org.springframework.core.env.get
|
import org.springframework.core.env.get
|
||||||
|
import org.springframework.messaging.simp.SimpMessagingTemplate
|
||||||
import org.springframework.web.bind.annotation.CrossOrigin
|
import org.springframework.web.bind.annotation.CrossOrigin
|
||||||
import org.springframework.web.bind.annotation.GetMapping
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
import org.springframework.web.bind.annotation.PathVariable
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
@ -17,6 +18,7 @@ import uk.co.neviyn.observationdatabase.GroupObservation
|
|||||||
import uk.co.neviyn.observationdatabase.GroupObservationInit
|
import uk.co.neviyn.observationdatabase.GroupObservationInit
|
||||||
import uk.co.neviyn.observationdatabase.GroupSessionManager
|
import uk.co.neviyn.observationdatabase.GroupSessionManager
|
||||||
import uk.co.neviyn.observationdatabase.Observation
|
import uk.co.neviyn.observationdatabase.Observation
|
||||||
|
import uk.co.neviyn.observationdatabase.ObservationRepository
|
||||||
import uk.co.neviyn.observationdatabase.Person
|
import uk.co.neviyn.observationdatabase.Person
|
||||||
import uk.co.neviyn.observationdatabase.PersonRepository
|
import uk.co.neviyn.observationdatabase.PersonRepository
|
||||||
import uk.co.neviyn.observationdatabase.SiteRepository
|
import uk.co.neviyn.observationdatabase.SiteRepository
|
||||||
@ -39,9 +41,11 @@ class GroupSessionController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
lateinit var tutorRepository: TutorRepository
|
lateinit var tutorRepository: TutorRepository
|
||||||
@Autowired
|
@Autowired
|
||||||
lateinit var observationsController: ObservationsController
|
lateinit var observationRepository: ObservationRepository
|
||||||
@Autowired
|
@Autowired
|
||||||
lateinit var personRepository: PersonRepository
|
lateinit var personRepository: PersonRepository
|
||||||
|
@Autowired
|
||||||
|
lateinit var websocketMessenger: SimpMessagingTemplate
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a new Group Observation session
|
* Start a new Group Observation session
|
||||||
@ -95,11 +99,27 @@ class GroupSessionController {
|
|||||||
return GroupSessionManager.isValid()
|
return GroupSessionManager.isValid()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save an Observation to the database
|
||||||
|
*/
|
||||||
|
fun saveObservation(observation: Observation): Observation {
|
||||||
|
logger.debug("Saving new Observation to database")
|
||||||
|
val committedObservation = observationRepository.save(observation)
|
||||||
|
logger.debug("Adding Observation data to Tutor records")
|
||||||
|
committedObservation.tutors.forEach {
|
||||||
|
it.observations.add(committedObservation)
|
||||||
|
tutorRepository.save(it)
|
||||||
|
}
|
||||||
|
logger.debug("Observation addition completed")
|
||||||
|
return committedObservation
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Submit an observation to be added to the session state and actual database
|
* Submit an observation to be added to the session state and actual database
|
||||||
*/
|
*/
|
||||||
@PostMapping("/submit")
|
@PostMapping("/submit")
|
||||||
fun addGroupObservation(observationData: GroupObservation) {
|
fun addGroupObservation(@Valid @RequestBody observationData: GroupObservation) {
|
||||||
|
val tutors = tutorRepository.findAllById(GroupSessionManager.tutors!!).toSet()
|
||||||
if (GroupSessionManager.isValid()) {
|
if (GroupSessionManager.isValid()) {
|
||||||
var observation = Observation(
|
var observation = Observation(
|
||||||
site = GroupSessionManager.site!!,
|
site = GroupSessionManager.site!!,
|
||||||
@ -115,11 +135,12 @@ class GroupSessionController {
|
|||||||
teamworkWorkload = observationData.scenarios.map { it.teamworkWorkload.rating }.average(),
|
teamworkWorkload = observationData.scenarios.map { it.teamworkWorkload.rating }.average(),
|
||||||
knowledge = observationData.scenarios.map { it.knowledge.rating }.average(),
|
knowledge = observationData.scenarios.map { it.knowledge.rating }.average(),
|
||||||
scenarios = observationData.scenarios,
|
scenarios = observationData.scenarios,
|
||||||
tutors = GroupSessionManager.tutors!!,
|
tutors = tutors,
|
||||||
person = personRepository.findFirstByNameLike(observationData.person.toUpperCase()) ?: personRepository.save(Person(name = observationData.person.toUpperCase()))
|
person = personRepository.findFirstByNameLike(observationData.person.toUpperCase()) ?: personRepository.save(Person(name = observationData.person.toUpperCase()))
|
||||||
)
|
)
|
||||||
observation = observationsController.saveObservation(observation)
|
observation = saveObservation(observation)
|
||||||
GroupSessionManager.addObservation(observation)
|
GroupSessionManager.addObservation(observation)
|
||||||
|
websocketMessenger.convertAndSend("/ws/observations", mapOf("observations" to GroupSessionManager.observations))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,11 @@
|
|||||||
{{ qrdata }}
|
{{ qrdata }}
|
||||||
</p>
|
</p>
|
||||||
</b-col>
|
</b-col>
|
||||||
|
<b-col>
|
||||||
|
<b-list-group v-for="(item, index) in data" v-bind:key="index">
|
||||||
|
<b-list-group-item>{{ item.person.name }}</b-list-group-item>
|
||||||
|
</b-list-group>
|
||||||
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
<b-row v-else>
|
<b-row v-else>
|
||||||
<b-col>
|
<b-col>
|
||||||
@ -118,7 +123,7 @@ export default {
|
|||||||
active: false,
|
active: false,
|
||||||
stompclient: null,
|
stompclient: null,
|
||||||
qrdata: "N/A",
|
qrdata: "N/A",
|
||||||
data: [],
|
data: [{person:{name:"No data yet received."}}],
|
||||||
site: null,
|
site: null,
|
||||||
tutors: null,
|
tutors: null,
|
||||||
siteOptions: [],
|
siteOptions: [],
|
||||||
@ -176,7 +181,7 @@ export default {
|
|||||||
)
|
)
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
console.log(response);
|
console.log(response);
|
||||||
if ('error' in response.data) {
|
if ("error" in response.data) {
|
||||||
} else {
|
} else {
|
||||||
let rdata = response.data;
|
let rdata = response.data;
|
||||||
self.qrdata = `http://${rdata.ip}:${rdata.port}/#/groupsession/${
|
self.qrdata = `http://${rdata.ip}:${rdata.port}/#/groupsession/${
|
||||||
@ -185,19 +190,18 @@ export default {
|
|||||||
self.active = true;
|
self.active = true;
|
||||||
self.stompclient = webstomp.over(
|
self.stompclient = webstomp.over(
|
||||||
new SockJS("http://127.0.0.1:8080/websocket", {
|
new SockJS("http://127.0.0.1:8080/websocket", {
|
||||||
heartbeat: false
|
heartbeat: true
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
self.stompclient.connect(
|
self.stompclient.connect([], function() {
|
||||||
[],
|
|
||||||
function() {
|
|
||||||
self.stompclient.subscribe("/ws/observations", function(
|
self.stompclient.subscribe("/ws/observations", function(
|
||||||
incomingData
|
incomingData
|
||||||
) {
|
) {
|
||||||
self.data = incomingData.content.observations;
|
self.data = JSON.parse(incomingData.body).observations;
|
||||||
|
console.log("data #")
|
||||||
|
console.log(self.data)
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
self.$refs.submissionModal.hide();
|
self.$refs.submissionModal.hide();
|
||||||
self.clearPassword();
|
self.clearPassword();
|
||||||
}
|
}
|
||||||
@ -213,7 +217,7 @@ export default {
|
|||||||
.get("/grpob/recover")
|
.get("/grpob/recover")
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
console.log(response);
|
console.log(response);
|
||||||
if ('error' in response.data) {
|
if ("error" in response.data) {
|
||||||
} else {
|
} else {
|
||||||
let rdata = response.data;
|
let rdata = response.data;
|
||||||
self.data = rdata.observations;
|
self.data = rdata.observations;
|
||||||
@ -228,16 +232,13 @@ export default {
|
|||||||
heartbeat: false
|
heartbeat: false
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
self.stompclient.connect(
|
self.stompclient.connect([], function() {
|
||||||
[],
|
|
||||||
function() {
|
|
||||||
self.stompclient.subscribe("/ws/observations", function(
|
self.stompclient.subscribe("/ws/observations", function(
|
||||||
incomingData
|
incomingData
|
||||||
) {
|
) {
|
||||||
self.data = incomingData.content.observations;
|
self.data = JSON.parse(incomingData.body).observations;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
self.$refs.submissionModal.hide();
|
self.$refs.submissionModal.hide();
|
||||||
self.clearPassword();
|
self.clearPassword();
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col cols="12" md="6" class="border">
|
<b-col cols="12" md="6" xl="3" class="border">
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col>
|
<b-col>
|
||||||
<h5>Monitoring</h5>
|
<h5>Monitoring</h5>
|
||||||
@ -75,7 +75,7 @@
|
|||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
</b-col>
|
</b-col>
|
||||||
<b-col cols="12" md="6" class="border">
|
<b-col cols="12" md="6" xl="3" class="border">
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col>
|
<b-col>
|
||||||
<h5>Control Procedural</h5>
|
<h5>Control Procedural</h5>
|
||||||
@ -106,9 +106,7 @@
|
|||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
<b-col cols="12" md="6" xl="3" class="border">
|
||||||
<b-row>
|
|
||||||
<b-col cols="12" md="6" class="border">
|
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col>
|
<b-col>
|
||||||
<h5>Control</h5>
|
<h5>Control</h5>
|
||||||
@ -139,7 +137,7 @@
|
|||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
</b-col>
|
</b-col>
|
||||||
<b-col cols="12" md="6" class="border">
|
<b-col cols="12" md="6" xl="3" class="border">
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col>
|
<b-col>
|
||||||
<h5>Conservatism</h5>
|
<h5>Conservatism</h5>
|
||||||
@ -170,9 +168,7 @@
|
|||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
<b-col cols="12" md="6" xl="3" class="border">
|
||||||
<b-row>
|
|
||||||
<b-col cols="12" md="6" class="border">
|
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col>
|
<b-col>
|
||||||
<h5>Teamwork Communications</h5>
|
<h5>Teamwork Communications</h5>
|
||||||
@ -203,7 +199,7 @@
|
|||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
</b-col>
|
</b-col>
|
||||||
<b-col cols="12" md="6" class="border">
|
<b-col cols="12" md="6" xl="3" class="border">
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col>
|
<b-col>
|
||||||
<h5>Teamwork Leadership</h5>
|
<h5>Teamwork Leadership</h5>
|
||||||
@ -234,9 +230,7 @@
|
|||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
<b-col cols="12" md="6" xl="3" class="border">
|
||||||
<b-row>
|
|
||||||
<b-col cols="12" md="6" class="border">
|
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col>
|
<b-col>
|
||||||
<h5>Teamwork Workload</h5>
|
<h5>Teamwork Workload</h5>
|
||||||
@ -267,7 +261,7 @@
|
|||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
</b-col>
|
</b-col>
|
||||||
<b-col cols="12" md="6" class="border">
|
<b-col cols="12" md="6" xl="3" class="border">
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col>
|
<b-col>
|
||||||
<h5>Knowledge</h5>
|
<h5>Knowledge</h5>
|
||||||
@ -305,7 +299,7 @@
|
|||||||
<b-button type="submit" variant="primary" v-on:click="onSubmit()">Submit</b-button>
|
<b-button type="submit" variant="primary" v-on:click="onSubmit()">Submit</b-button>
|
||||||
</b-form>
|
</b-form>
|
||||||
</b-container>
|
</b-container>
|
||||||
<b-modal id="submissionModal" ref="submissionModal" title="Confirm Submission" @ok="handleOk">
|
<b-modal id="submissionModal" ref="submissionModal" title="Confirm Submission" @ok="actuallySubmit()">
|
||||||
<form @submit.stop.prevent="handleSubmit">
|
<form @submit.stop.prevent="handleSubmit">
|
||||||
<p>Once submitted, data cannot be changed.</p>
|
<p>Once submitted, data cannot be changed.</p>
|
||||||
<p>Are you sure you wish to submit?</p>
|
<p>Are you sure you wish to submit?</p>
|
||||||
@ -411,15 +405,17 @@ export default {
|
|||||||
showModal() {
|
showModal() {
|
||||||
this.$refs.submissionModal.show();
|
this.$refs.submissionModal.show();
|
||||||
},
|
},
|
||||||
handleSubmit() {
|
actuallySubmit() {
|
||||||
|
var self = this;
|
||||||
|
var payload = {
|
||||||
|
person: self.participant,
|
||||||
|
scenarios: self.scenarios
|
||||||
|
}
|
||||||
var form = document.getElementById("submission-form");
|
var form = document.getElementById("submission-form");
|
||||||
if (form.checkValidity()) {
|
if (form.checkValidity()) {
|
||||||
var self = this;
|
console.log(payload)
|
||||||
Vue.axios
|
Vue.axios
|
||||||
.post("/grpob/submit", {
|
.post("/grpob/submit", payload)
|
||||||
person: self.participant,
|
|
||||||
scenarios: JSON.parse(JSON.stringify(self.scenarios))
|
|
||||||
})
|
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
self.complete = true;
|
self.complete = true;
|
||||||
console.log(response);
|
console.log(response);
|
||||||
@ -434,3 +430,14 @@ export default {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.strength {
|
||||||
|
background-color: honeydew;
|
||||||
|
}
|
||||||
|
.afi {
|
||||||
|
background-color: mistyrose;
|
||||||
|
}
|
||||||
|
.bottom-buffer {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
</b-row>
|
</b-row>
|
||||||
<b-row class="my-3" align-h="center">
|
<b-row class="my-3" align-h="center">
|
||||||
<b-col lg="6" sm="12">
|
<b-col lg="6" sm="12">
|
||||||
<b-button disabled variant="outline-secondary" class="scale-in-center" size="lg" to="/groupsession" block><v-icon name="users"/> Start a Group Session <b-badge variant="info">Coming Soon!</b-badge></b-button>
|
<b-button class="scale-in-center" size="lg" to="/groupsession" block><v-icon name="users"/> Start a Group Session</b-button>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
</b-container>
|
</b-container>
|
||||||
|
Loading…
Reference in New Issue
Block a user