Group sessions can now be properly started
This commit is contained in:
parent
cd6aba097d
commit
2676307170
@ -40,7 +40,7 @@ class CustomWebSecurityConfigurerAdapter : WebSecurityConfigurerAdapter() {
|
|||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
override fun configure(http: HttpSecurity) {
|
override fun configure(http: HttpSecurity) {
|
||||||
http.csrf().disable().authorizeRequests()
|
http.csrf().disable().authorizeRequests()
|
||||||
.antMatchers(HttpMethod.POST, "/api/site", "/api/tutor", "/api/observation").authenticated()
|
.antMatchers(HttpMethod.POST, "/api/site", "/api/tutor", "/api/observation", "/api/grpob/start").authenticated()
|
||||||
.anyRequest().permitAll()
|
.anyRequest().permitAll()
|
||||||
.and()
|
.and()
|
||||||
.httpBasic()
|
.httpBasic()
|
||||||
|
@ -15,6 +15,6 @@ class WebSocketConfig : WebSocketMessageBrokerConfigurer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun registerStompEndpoints(registry: StompEndpointRegistry) {
|
override fun registerStompEndpoints(registry: StompEndpointRegistry) {
|
||||||
registry.addEndpoint("/websocket").withSockJS()
|
registry.addEndpoint("/websocket").setAllowedOrigins("http://localhost:8080", "http://127.0.0.1:8080").withSockJS()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,6 +10,7 @@ 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
|
||||||
import org.springframework.web.bind.annotation.PostMapping
|
import org.springframework.web.bind.annotation.PostMapping
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
import org.springframework.web.bind.annotation.RequestMapping
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
import org.springframework.web.bind.annotation.RestController
|
import org.springframework.web.bind.annotation.RestController
|
||||||
import uk.co.neviyn.observationdatabase.GroupObservation
|
import uk.co.neviyn.observationdatabase.GroupObservation
|
||||||
@ -22,6 +23,7 @@ import uk.co.neviyn.observationdatabase.SiteRepository
|
|||||||
import uk.co.neviyn.observationdatabase.TutorRepository
|
import uk.co.neviyn.observationdatabase.TutorRepository
|
||||||
import java.net.Inet4Address
|
import java.net.Inet4Address
|
||||||
import java.net.NetworkInterface
|
import java.net.NetworkInterface
|
||||||
|
import javax.validation.Valid
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/grpob")
|
@RequestMapping("/api/grpob")
|
||||||
@ -45,7 +47,7 @@ class GroupSessionController {
|
|||||||
* Start a new Group Observation session
|
* Start a new Group Observation session
|
||||||
*/
|
*/
|
||||||
@PostMapping("/start")
|
@PostMapping("/start")
|
||||||
fun startGroupObservation(initData: GroupObservationInit): Map<String, String> {
|
fun startGroupObservation(@Valid @RequestBody initData: GroupObservationInit): Map<String, String> {
|
||||||
val site = siteRepository.findById(initData.site)
|
val site = siteRepository.findById(initData.site)
|
||||||
val tutors = tutorRepository.findAllById(initData.tutors).toSet()
|
val tutors = tutorRepository.findAllById(initData.tutors).toSet()
|
||||||
if (!site.isPresent) {
|
if (!site.isPresent) {
|
||||||
@ -65,8 +67,12 @@ class GroupSessionController {
|
|||||||
*/
|
*/
|
||||||
@GetMapping("/recover")
|
@GetMapping("/recover")
|
||||||
fun reconnectToGroupObservation(): Map<String, Any> {
|
fun reconnectToGroupObservation(): Map<String, Any> {
|
||||||
logger.debug("Previous group observation requested")
|
if (GroupSessionManager.isValid()) {
|
||||||
return getConnectionDetails().plus(mapOf("id" to GroupSessionManager.sessionId.toString(), "observations" to GroupSessionManager.observations))
|
logger.info("Previous group observation requested, current id ${GroupSessionManager.sessionId}")
|
||||||
|
return getConnectionDetails().plus(mapOf("id" to GroupSessionManager.sessionId.toString(), "observations" to GroupSessionManager.observations))
|
||||||
|
}
|
||||||
|
logger.info("Tried to recover a session but no session is active")
|
||||||
|
return mapOf("error" to "No session currently active")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
</b-row>
|
</b-row>
|
||||||
<b-row v-else>
|
<b-row v-else>
|
||||||
<b-col>
|
<b-col>
|
||||||
<b-form id="submission-form" novalidate>
|
<b-form id="submission-form" novalidate @submit="onSubmit">
|
||||||
<b-row align-h="center">
|
<b-row align-h="center">
|
||||||
<b-col>
|
<b-col>
|
||||||
<b-form-group label="Site">
|
<b-form-group label="Site">
|
||||||
@ -43,17 +43,65 @@
|
|||||||
</b-form-group>
|
</b-form-group>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
|
<b-row
|
||||||
|
v-for="(item, index) in scenarioTitles"
|
||||||
|
v-bind:key="index"
|
||||||
|
class="border bottom-buffer"
|
||||||
|
fluid
|
||||||
|
>
|
||||||
|
<b-col>
|
||||||
|
<b-form-input
|
||||||
|
v-model="item.data"
|
||||||
|
type="text"
|
||||||
|
placeholder="Enter scenario description."
|
||||||
|
></b-form-input>
|
||||||
|
</b-col>
|
||||||
|
<b-col cols="1">
|
||||||
|
<b-button v-on:click="scenarioTitles.splice(index, 1)" variant="danger">
|
||||||
|
<b>Delete</b>
|
||||||
|
</b-button>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
<b-row align-h="center">
|
||||||
|
<b-col>
|
||||||
|
<b-button
|
||||||
|
v-on:click="scenarioTitles.push({data:''})"
|
||||||
|
size="lg"
|
||||||
|
variant="primary"
|
||||||
|
>Add Another Scenario</b-button>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
<b-row>
|
||||||
|
<b-col>
|
||||||
|
<br>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
<b-row align-h="center">
|
<b-row align-h="center">
|
||||||
<b-col>
|
<b-col>
|
||||||
<b-button type="submit" size="lg" variant="primary">Start</b-button>
|
<b-button type="submit" size="lg" variant="primary">Start</b-button>
|
||||||
</b-col>
|
</b-col>
|
||||||
<b-col>
|
<b-col>
|
||||||
<b-button size="lg" variant="secondary">Connect to Previous Session</b-button>
|
<b-button
|
||||||
|
size="lg"
|
||||||
|
variant="secondary"
|
||||||
|
v-on:click="connectToPrevious()"
|
||||||
|
>Connect to Previous Session</b-button>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
</b-form>
|
</b-form>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
|
<b-modal
|
||||||
|
id="submissionModal"
|
||||||
|
ref="submissionModal"
|
||||||
|
title="Enter password to confirm submission"
|
||||||
|
@ok="handleOk"
|
||||||
|
@shown="clearPassword"
|
||||||
|
>
|
||||||
|
<form @submit.stop.prevent="handleSubmit">
|
||||||
|
<b-form-input type="password" placeholder="Enter password" v-model="submitPassword"></b-form-input>
|
||||||
|
</form>
|
||||||
|
</b-modal>
|
||||||
</b-container>
|
</b-container>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
@ -75,7 +123,7 @@ export default {
|
|||||||
tutors: null,
|
tutors: null,
|
||||||
siteOptions: [],
|
siteOptions: [],
|
||||||
tutorOptions: [],
|
tutorOptions: [],
|
||||||
scenarioTitles: null,
|
scenarioTitles: [{ data: "" }, { data: "" }, { data: "" }],
|
||||||
type: null,
|
type: null,
|
||||||
submitPassword: null
|
submitPassword: null
|
||||||
};
|
};
|
||||||
@ -88,15 +136,6 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
console.log("loading");
|
console.log("loading");
|
||||||
var self = this;
|
|
||||||
this.stompclient.connect(
|
|
||||||
[],
|
|
||||||
function() {
|
|
||||||
self.stompclient.subscribe("/ws/observations", function(incomingData) {
|
|
||||||
self.data = incomingData.content.observations;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
Vue.axios
|
Vue.axios
|
||||||
.get("/site")
|
.get("/site")
|
||||||
.then(response => {
|
.then(response => {
|
||||||
@ -104,39 +143,112 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
if (error.response.status === 404) {
|
if (error.response.status === 404) {
|
||||||
this.$router.push("/dberror");
|
//this.$router.push("/dberror");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
startSession: function() {
|
startSession: function() {
|
||||||
|
var self = this;
|
||||||
let axiosConfig = {
|
let axiosConfig = {
|
||||||
auth: {
|
auth: {
|
||||||
username: "admin",
|
username: "admin",
|
||||||
password: this.submitPassword
|
password: this.submitPassword
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
console.log({
|
||||||
|
site: self.site,
|
||||||
|
tutors: self.tutors,
|
||||||
|
scenarioTitles: self.scenarioTitles.map(x => x.data),
|
||||||
|
type: self.type
|
||||||
|
});
|
||||||
Vue.axios
|
Vue.axios
|
||||||
.post(
|
.post(
|
||||||
"/grpob/start",
|
"/grpob/start",
|
||||||
{
|
{
|
||||||
site: this.site,
|
site: self.site,
|
||||||
tutors: this.tutors,
|
tutors: self.tutors,
|
||||||
scenarioTitles: this.whom,
|
scenarioTitles: self.scenarioTitles.map(x => x.data),
|
||||||
type: this.type
|
type: self.type
|
||||||
},
|
},
|
||||||
axiosConfig
|
axiosConfig
|
||||||
)
|
)
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
console.log(response);
|
console.log(response);
|
||||||
this.qrdata =
|
if ('error' in response.data) {
|
||||||
"http://" + response.ip + ":" + response.port + "/#/" + response.id;
|
} else {
|
||||||
|
let rdata = response.data;
|
||||||
|
self.qrdata = `http://${rdata.ip}:${rdata.port}/#/groupsession/${
|
||||||
|
rdata.id
|
||||||
|
}`;
|
||||||
|
self.active = true;
|
||||||
|
self.stompclient = webstomp.over(
|
||||||
|
new SockJS("http://127.0.0.1:8080/websocket", {
|
||||||
|
heartbeat: false
|
||||||
|
})
|
||||||
|
);
|
||||||
|
self.stompclient.connect(
|
||||||
|
[],
|
||||||
|
function() {
|
||||||
|
self.stompclient.subscribe("/ws/observations", function(
|
||||||
|
incomingData
|
||||||
|
) {
|
||||||
|
self.data = incomingData.content.observations;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
self.$refs.submissionModal.hide();
|
||||||
|
self.clearPassword();
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(function(error) {
|
.catch(function(error) {
|
||||||
|
self.active = false;
|
||||||
console.log(error);
|
console.log(error);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
connectToPrevious: function() {
|
||||||
|
var self = this;
|
||||||
|
Vue.axios
|
||||||
|
.get("/grpob/recover")
|
||||||
|
.then(function(response) {
|
||||||
|
console.log(response);
|
||||||
|
if ('error' in response.data) {
|
||||||
|
} else {
|
||||||
|
let rdata = response.data;
|
||||||
|
self.data = rdata.observations;
|
||||||
|
self.qrdata = `http://${rdata.ip}:${rdata.port}/#/groupsession/${
|
||||||
|
rdata.id
|
||||||
|
}`;
|
||||||
|
console.log(self.active);
|
||||||
|
self.active = true;
|
||||||
|
console.log(self.active);
|
||||||
|
self.stompclient = webstomp.over(
|
||||||
|
new SockJS("http://127.0.0.1:8080/websocket", {
|
||||||
|
heartbeat: false
|
||||||
|
})
|
||||||
|
);
|
||||||
|
self.stompclient.connect(
|
||||||
|
[],
|
||||||
|
function() {
|
||||||
|
self.stompclient.subscribe("/ws/observations", function(
|
||||||
|
incomingData
|
||||||
|
) {
|
||||||
|
self.data = incomingData.content.observations;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
self.$refs.submissionModal.hide();
|
||||||
|
self.clearPassword();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(function(error) {
|
||||||
|
if (error.response.status === 404) {
|
||||||
|
this.$router.push("/dberror");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
getTutors: function() {
|
getTutors: function() {
|
||||||
if (this.site != null) {
|
if (this.site != null) {
|
||||||
Vue.axios
|
Vue.axios
|
||||||
@ -151,6 +263,28 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
onSubmit: function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
var form = document.getElementById("submission-form");
|
||||||
|
if (form.checkValidity()) {
|
||||||
|
this.showModal();
|
||||||
|
}
|
||||||
|
form.classList.add("was-validated");
|
||||||
|
},
|
||||||
|
showModal() {
|
||||||
|
this.$refs.submissionModal.show();
|
||||||
|
},
|
||||||
|
clearPassword() {
|
||||||
|
this.submitPassword = null;
|
||||||
|
},
|
||||||
|
handleOk(evt) {
|
||||||
|
// Prevent modal from closing
|
||||||
|
evt.preventDefault();
|
||||||
|
if (this.submitPassword !== null) {
|
||||||
|
this.startSession();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<b-container fluid>
|
<b-container fluid>
|
||||||
<b-container
|
<b-container v-if="!valid">
|
||||||
|
<p>Getting session data from server</p>
|
||||||
|
</b-container>
|
||||||
|
<b-container v-else-if="scenarios.length === 0">
|
||||||
|
<p>No scenarios defined for this session, please setup a new group session</p>
|
||||||
|
</b-container>
|
||||||
|
<b-container v-else
|
||||||
v-for="(item, index) in scenarios"
|
v-for="(item, index) in scenarios"
|
||||||
v-bind:key="index"
|
v-bind:key="index"
|
||||||
class="border bottom-buffer"
|
class="border bottom-buffer"
|
||||||
@ -288,28 +294,31 @@ export default {
|
|||||||
scenarios: [],
|
scenarios: [],
|
||||||
totals: [0, 0, 0, 0, 0, 0, 0, 0],
|
totals: [0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
warningBound: 2.5,
|
warningBound: 2.5,
|
||||||
submitPassword: null
|
submitPassword: null,
|
||||||
|
valid: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
/*
|
let self = this;
|
||||||
if (this.id != null) {
|
if (this.id != null) {
|
||||||
Vue.axios
|
Vue.axios
|
||||||
.get("/grpob/valid/" + this.id)
|
.get(`/grpob/valid/${this.id}`)
|
||||||
.then(response => {
|
.then(function (response) {
|
||||||
response.titles.forEach(function(x) {
|
if(response.data.titles != null) {
|
||||||
this.addAnotherObservation(x);
|
response.data.titles.forEach(function(x) {
|
||||||
});
|
self.addAnotherObservation(x);
|
||||||
|
})
|
||||||
|
self.valid = true
|
||||||
|
};
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(function(error) {
|
||||||
if (error.response.status === 404) {
|
if (error.response.status === 404) {
|
||||||
this.$router.push("/dberror");
|
self.$router.push("/dberror");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
console.log(error)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
this.addAnotherObservation("Sample Entry");
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
addAnotherObservation: function(newTitle) {
|
addAnotherObservation: function(newTitle) {
|
||||||
@ -436,5 +445,3 @@ export default {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
Loading…
Reference in New Issue
Block a user