Started websocket frontend component

This commit is contained in:
neviyn 2019-02-13 20:21:15 +00:00
parent d30104eafa
commit b28bc5a7f1
6 changed files with 231 additions and 163 deletions

View File

@ -1,6 +1,7 @@
package uk.co.neviyn.observationdatabase package uk.co.neviyn.observationdatabase
import org.joda.time.LocalDate import org.joda.time.LocalDate
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
import org.springframework.cache.annotation.Cacheable import org.springframework.cache.annotation.Cacheable
import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.GetMapping
@ -19,6 +20,8 @@ import javax.validation.Valid
@CrossOrigin @CrossOrigin
class Controller { class Controller {
val logger = LoggerFactory.getLogger(javaClass)
@Autowired @Autowired
lateinit var websocketMessenger: SimpMessagingTemplate lateinit var websocketMessenger: SimpMessagingTemplate
@ -42,6 +45,7 @@ class Controller {
*/ */
@PostMapping("/site") @PostMapping("/site")
fun addSite(@Valid @RequestBody newSite: NewSite): NameValue { fun addSite(@Valid @RequestBody newSite: NewSite): NameValue {
logger.debug("Attempting to add Site\n$newSite")
val site = siteRepository.save(Site(name = newSite.name)) val site = siteRepository.save(Site(name = newSite.name))
return NameValue(site.name, site.id) return NameValue(site.name, site.id)
} }
@ -70,6 +74,7 @@ class Controller {
*/ */
@PostMapping("/tutor") @PostMapping("/tutor")
fun addTutor(@Valid @RequestBody newTutor: NewTutor): NameValue? { fun addTutor(@Valid @RequestBody newTutor: NewTutor): NameValue? {
logger.debug("Attempting to add tutor\n$newTutor")
var nameValue: NameValue? = null var nameValue: NameValue? = null
siteRepository.findById(newTutor.siteId).ifPresent { siteRepository.findById(newTutor.siteId).ifPresent {
val tutor = tutorRepository.save(Tutor(name = newTutor.name, site = it)) val tutor = tutorRepository.save(Tutor(name = newTutor.name, site = it))
@ -87,8 +92,14 @@ class Controller {
fun addObservation(@Valid @RequestBody newObservation: NewObservation): Long? { fun addObservation(@Valid @RequestBody newObservation: NewObservation): Long? {
val site = siteRepository.findById(newObservation.site) val site = siteRepository.findById(newObservation.site)
val tutors = tutorRepository.findAllById(newObservation.tutors).toSet() val tutors = tutorRepository.findAllById(newObservation.tutors).toSet()
if (!site.isPresent) return null if (!site.isPresent) {
if (tutors.isEmpty() || tutors.size != newObservation.tutors.size) return null logger.info("Attempted to add Observation without a site.")
return null
}
if (tutors.isEmpty() || tutors.size != newObservation.tutors.size) {
logger.info("Attempted to add Observation without a tutor")
return null
}
var observation = Observation( var observation = Observation(
site = site.get(), site = site.get(),
date = LocalDate.now(), date = LocalDate.now(),
@ -106,12 +117,15 @@ class Controller {
tutors = tutors, tutors = tutors,
person = personRepository.findFirstByNameLike(newObservation.person.toUpperCase()) ?: personRepository.save(Person(name = newObservation.person.toUpperCase())) person = personRepository.findFirstByNameLike(newObservation.person.toUpperCase()) ?: personRepository.save(Person(name = newObservation.person.toUpperCase()))
) )
logger.debug("Saving new Observation to database")
observation = observationRepository.save(observation) observation = observationRepository.save(observation)
logger.debug("Adding Observation data to Tutor records")
tutors.forEach { tutors.forEach {
it.observations.add(observation) it.observations.add(observation)
tutorRepository.save(it) tutorRepository.save(it)
} }
sendObservationToSocket(observation) sendObservationToSocket(observation)
logger.debug("Observation addition completed")
return observation.id return observation.id
} }
@ -121,22 +135,28 @@ class Controller {
@PostMapping("/observations") @PostMapping("/observations")
@Cacheable("observations", key = "#observationsRequest") @Cacheable("observations", key = "#observationsRequest")
fun getObservations(@Valid @RequestBody observationsRequest: ObservationsRequest): List<Observation> { fun getObservations(@Valid @RequestBody observationsRequest: ObservationsRequest): List<Observation> {
logger.debug("Observation request received")
if (observationsRequest.tutor != null) { if (observationsRequest.tutor != null) {
logger.debug("Observation contains a tutor")
return tutorRepository.findById(observationsRequest.tutor).map { return tutorRepository.findById(observationsRequest.tutor).map {
observationRepository.findByTutorsAndDateBetweenOrderByDateAsc(tutor = it, observationRepository.findByTutorsAndDateBetweenOrderByDateAsc(tutor = it,
startDate = observationsRequest.startDate, startDate = observationsRequest.startDate,
endDate = observationsRequest.endDate) endDate = observationsRequest.endDate)
}.orElse(listOf()) }.orElse(listOf())
} else if (observationsRequest.person != null && observationsRequest.person.isNotEmpty() && observationsRequest.site != null) { } else if (observationsRequest.person != null && observationsRequest.person.isNotEmpty() && observationsRequest.site != null) {
logger.debug("Observation contains a person")
val person = personRepository.findFirstByNameLike(observationsRequest.person.toUpperCase()) ?: return listOf() val person = personRepository.findFirstByNameLike(observationsRequest.person.toUpperCase()) ?: return listOf()
val site = siteRepository.findById(observationsRequest.site).get() val site = siteRepository.findById(observationsRequest.site).get()
return observationRepository.findBySiteAndPersonAndDateBetweenOrderByDateAsc(site, person, observationsRequest.startDate, observationsRequest.endDate) return observationRepository.findBySiteAndPersonAndDateBetweenOrderByDateAsc(site, person, observationsRequest.startDate, observationsRequest.endDate)
} else if (observationsRequest.site != null) { } else if (observationsRequest.site != null) {
logger.debug("Observation contains a site")
return siteRepository.findById(observationsRequest.site).map { return siteRepository.findById(observationsRequest.site).map {
observationRepository.findBySiteAndDateBetweenOrderByDateAsc(site = it, observationRepository.findBySiteAndDateBetweenOrderByDateAsc(site = it,
startDate = observationsRequest.startDate, startDate = observationsRequest.startDate,
endDate = observationsRequest.endDate) endDate = observationsRequest.endDate)
}.orElse(listOf()) }.orElse(listOf())
} else {
logger.error("Observation request contains no data from which a request can be made\n$observationsRequest")
} }
return listOf() return listOf()
} }
@ -191,11 +211,13 @@ class Controller {
} }
val data = getObservations(observationsRequest) val data = getObservations(observationsRequest)
if (data.isEmpty()) return null if (data.isEmpty()) return null
logger.debug("Building CSV")
val builder = StringBuilder(csvHeaderString()) val builder = StringBuilder(csvHeaderString())
data.forEach { data.forEach {
builder.append('\n') builder.append('\n')
builder.append(it.toCsvFormat()) builder.append(it.toCsvFormat())
} }
logger.debug("Returning constructed CSV")
return builder.toString() return builder.toString()
} }
@ -209,6 +231,7 @@ class Controller {
var control = 0 var control = 0
var conservatism = 0 var conservatism = 0
var teamwork = 0 var teamwork = 0
logger.debug("Calculating AFI Data for ${data.size} entries")
for (x in data) { for (x in data) {
for (y in x.scenarios) { for (y in x.scenarios) {
if (y.monitoring.rating <= afiPieThreshold) if (y.monitoring.rating <= afiPieThreshold)
@ -233,11 +256,16 @@ class Controller {
} }
fun sendObservationToSocket(observation: Observation) { fun sendObservationToSocket(observation: Observation) {
if (::websocketMessenger.isInitialized) {
websocketMessenger.convertAndSend("/ws/observations", observation) websocketMessenger.convertAndSend("/ws/observations", observation)
} else {
logger.warn("WebSocket messenger is not initialized. Not sending data to socket.")
}
} }
@GetMapping("/address") @GetMapping("/address")
fun getConnectionDetails(): Map<String, String> { fun getConnectionDetails(): Map<String, String> {
websocketMessenger.convertAndSend("/ws/observations", "Hello World")
return mapOf("ip" to InetAddress.getLocalHost().hostAddress) return mapOf("ip" to InetAddress.getLocalHost().hostAddress)
} }
} }

View File

@ -1391,9 +1391,9 @@
"dev": true "dev": true
}, },
"ansi-colors": { "ansi-colors": {
"version": "3.0.5", "version": "3.2.3",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.0.5.tgz", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz",
"integrity": "sha512-VVjWpkfaphxUBFarydrQ3n26zX5nIK7hcbT3/ielrvwDDyBBjuh2vuSw1P9zkPq0cfqvdw7lkYHnu+OLSfIBsg==", "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==",
"dev": true "dev": true
}, },
"ansi-escapes": { "ansi-escapes": {
@ -1786,12 +1786,6 @@
"integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=",
"dev": true "dev": true
}, },
"array-find-index": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
"integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
"dev": true
},
"array-flatten": { "array-flatten": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
@ -2700,9 +2694,9 @@
}, },
"dependencies": { "dependencies": {
"array-flatten": { "array-flatten": {
"version": "2.1.1", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
"integrity": "sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=", "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==",
"dev": true "dev": true
} }
} }
@ -3512,12 +3506,12 @@
"dev": true "dev": true
}, },
"compressible": { "compressible": {
"version": "2.0.14", "version": "2.0.15",
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.14.tgz", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.15.tgz",
"integrity": "sha1-MmxfUH+7BV9UEWeCuWmoG2einac=", "integrity": "sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==",
"dev": true, "dev": true,
"requires": { "requires": {
"mime-db": ">= 1.34.0 < 2" "mime-db": ">= 1.36.0 < 2"
} }
}, },
"compression": { "compression": {
@ -3603,9 +3597,9 @@
} }
}, },
"connect-history-api-fallback": { "connect-history-api-fallback": {
"version": "1.5.0", "version": "1.6.0",
"resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz",
"integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=", "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==",
"dev": true "dev": true
}, },
"console-browserify": { "console-browserify": {
@ -4202,15 +4196,6 @@
"cssom": "0.3.x" "cssom": "0.3.x"
} }
}, },
"currently-unhandled": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
"integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
"dev": true,
"requires": {
"array-find-index": "^1.0.1"
}
},
"cyclist": { "cyclist": {
"version": "0.2.2", "version": "0.2.2",
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz",
@ -5032,12 +5017,12 @@
"dev": true "dev": true
}, },
"eventsource": { "eventsource": {
"version": "0.1.6", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz", "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz",
"integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=", "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"original": ">=0.0.5" "original": "^1.0.0"
} }
}, },
"evp_bytestokey": { "evp_bytestokey": {
@ -6625,9 +6610,9 @@
} }
}, },
"handle-thing": { "handle-thing": {
"version": "1.2.5", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.5.tgz", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz",
"integrity": "sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ=", "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==",
"dev": true "dev": true
}, },
"handlebars": { "handlebars": {
@ -6988,9 +6973,9 @@
} }
}, },
"http-parser-js": { "http-parser-js": {
"version": "0.4.13", "version": "0.5.0",
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.13.tgz", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz",
"integrity": "sha1-O9bW/ebjFyyTNMOzO2wZPYD+ETc=", "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==",
"dev": true "dev": true
}, },
"http-proxy": { "http-proxy": {
@ -8951,16 +8936,6 @@
"js-tokens": "^3.0.0 || ^4.0.0" "js-tokens": "^3.0.0 || ^4.0.0"
} }
}, },
"loud-rejection": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
"integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
"dev": true,
"requires": {
"currently-unhandled": "^0.4.1",
"signal-exit": "^3.0.0"
}
},
"lower-case": { "lower-case": {
"version": "1.1.4", "version": "1.1.4",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz",
@ -9002,9 +8977,9 @@
"dev": true "dev": true
}, },
"map-age-cleaner": { "map-age-cleaner": {
"version": "0.1.2", "version": "0.1.3",
"resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.2.tgz", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
"integrity": "sha512-UN1dNocxQq44IhJyMI4TU8phc2m9BddacHRPRjKGLYaF0jqd3xLz0jS0skpAU9WgYyoR4gHtUpzytNBS385FWQ==", "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
"dev": true, "dev": true,
"requires": { "requires": {
"p-defer": "^1.0.0" "p-defer": "^1.0.0"
@ -10029,9 +10004,9 @@
"dev": true "dev": true
}, },
"p-is-promise": { "p-is-promise": {
"version": "1.1.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz",
"integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==",
"dev": true "dev": true
}, },
"p-limit": { "p-limit": {
@ -11607,9 +11582,9 @@
"dev": true "dev": true
}, },
"querystringify": { "querystringify": {
"version": "2.0.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.0.0.tgz", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.0.tgz",
"integrity": "sha512-eTPo5t/4bgaMNZxyjWx6N2a6AuE0mq51KWvpc7nU/MAqixcI6v6KrGUKES0HaomdnolQBBXU/++X6/QQ9KL4tw==", "integrity": "sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg==",
"dev": true "dev": true
}, },
"randomatic": { "randomatic": {
@ -12854,9 +12829,9 @@
"dev": true "dev": true
}, },
"selfsigned": { "selfsigned": {
"version": "1.10.3", "version": "1.10.4",
"resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.3.tgz", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.4.tgz",
"integrity": "sha512-vmZenZ+8Al3NLHkWnhBQ0x6BkML1eCP2xEi3JE+f3D9wW9fipD9NNJHYtE9XJM4TsPaHGZJIamrSI6MTg1dU2Q==", "integrity": "sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==",
"dev": true, "dev": true,
"requires": { "requires": {
"node-forge": "0.7.5" "node-forge": "0.7.5"
@ -13229,28 +13204,19 @@
} }
}, },
"sockjs-client": { "sockjs-client": {
"version": "1.1.5", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.5.tgz", "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.3.0.tgz",
"integrity": "sha1-G7fA9yIsQPQq3xT0RCy9Eml3GoM=", "integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==",
"dev": true, "dev": true,
"requires": { "requires": {
"debug": "^2.6.6", "debug": "^3.2.5",
"eventsource": "0.1.6", "eventsource": "^1.0.7",
"faye-websocket": "~0.11.0", "faye-websocket": "~0.11.1",
"inherits": "^2.0.1", "inherits": "^2.0.3",
"json3": "^3.3.2", "json3": "^3.3.2",
"url-parse": "^1.1.8" "url-parse": "^1.4.3"
}, },
"dependencies": { "dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
},
"faye-websocket": { "faye-websocket": {
"version": "0.11.1", "version": "0.11.1",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz",
@ -13259,12 +13225,6 @@
"requires": { "requires": {
"websocket-driver": ">=0.5.1" "websocket-driver": ">=0.5.1"
} }
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true
} }
} }
}, },
@ -13341,65 +13301,62 @@
"dev": true "dev": true
}, },
"spdy": { "spdy": {
"version": "3.4.7", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/spdy/-/spdy-3.4.7.tgz", "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.0.tgz",
"integrity": "sha1-Qv9B7OXMD5mjpsKKq7c/XDsDrLw=", "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==",
"dev": true, "dev": true,
"requires": { "requires": {
"debug": "^2.6.8", "debug": "^4.1.0",
"handle-thing": "^1.2.5", "handle-thing": "^2.0.0",
"http-deceiver": "^1.2.7", "http-deceiver": "^1.2.7",
"safe-buffer": "^5.0.1",
"select-hose": "^2.0.0", "select-hose": "^2.0.0",
"spdy-transport": "^2.0.18" "spdy-transport": "^3.0.0"
}, },
"dependencies": { "dependencies": {
"debug": { "debug": {
"version": "2.6.9", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true, "dev": true,
"requires": { "requires": {
"ms": "2.0.0" "ms": "^2.1.1"
} }
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true
} }
} }
}, },
"spdy-transport": { "spdy-transport": {
"version": "2.1.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.1.0.tgz", "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz",
"integrity": "sha512-bpUeGpZcmZ692rrTiqf9/2EUakI6/kXX1Rpe0ib/DyOzbiexVfXkw6GnvI9hVGvIwVaUhkaBojjCZwLNRGQg1g==", "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==",
"dev": true, "dev": true,
"requires": { "requires": {
"debug": "^2.6.8", "debug": "^4.1.0",
"detect-node": "^2.0.3", "detect-node": "^2.0.4",
"hpack.js": "^2.1.6", "hpack.js": "^2.1.6",
"obuf": "^1.1.1", "obuf": "^1.1.2",
"readable-stream": "^2.2.9", "readable-stream": "^3.0.6",
"safe-buffer": "^5.0.1", "wbuf": "^1.7.3"
"wbuf": "^1.7.2"
}, },
"dependencies": { "dependencies": {
"debug": { "debug": {
"version": "2.6.9", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true, "dev": true,
"requires": { "requires": {
"ms": "2.0.0" "ms": "^2.1.1"
} }
}, },
"ms": { "readable-stream": {
"version": "2.0.0", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==",
"dev": true "dev": true,
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
} }
} }
}, },
@ -13792,9 +13749,9 @@
} }
}, },
"thunky": { "thunky": {
"version": "1.0.2", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.2.tgz", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz",
"integrity": "sha1-qGLgGOP7HqLsP85dVWBc9X8kc3E=", "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==",
"dev": true "dev": true
}, },
"timers-browserify": { "timers-browserify": {
@ -14267,12 +14224,6 @@
} }
} }
}, },
"url-join": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.0.tgz",
"integrity": "sha1-TTNA6AfTdzvamZH4MFrNzCpmXSo=",
"dev": true
},
"url-loader": { "url-loader": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.1.1.tgz", "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.1.1.tgz",
@ -14328,9 +14279,9 @@
} }
}, },
"url-parse": { "url-parse": {
"version": "1.4.3", "version": "1.4.4",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.3.tgz", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.4.tgz",
"integrity": "sha512-rh+KuAW36YKo0vClhQzLLveoj8FwPJNu65xLb7Mrt+eZht0IPT0IXgSv8gcMegZ6NvjJUALf6Mf25POlMwD1Fw==", "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==",
"dev": true, "dev": true,
"requires": { "requires": {
"querystringify": "^2.0.0", "querystringify": "^2.0.0",
@ -15025,24 +14976,21 @@
} }
}, },
"webpack-dev-middleware": { "webpack-dev-middleware": {
"version": "3.2.0", "version": "3.4.0",
"resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.2.0.tgz", "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.4.0.tgz",
"integrity": "sha512-YJLMF/96TpKXaEQwaLEo+Z4NDK8aV133ROF6xp9pe3gQoS7sxfpXh4Rv9eC+8vCvWfmDjRQaMSlRPbO+9G6jgA==", "integrity": "sha512-Q9Iyc0X9dP9bAsYskAVJ/hmIZZQwf/3Sy4xCAZgL5cUkjZmUZLt4l5HpbST/Pdgjn3u6pE7u5OdGd1apgzRujA==",
"dev": true, "dev": true,
"requires": { "requires": {
"loud-rejection": "^1.6.0",
"memory-fs": "~0.4.1", "memory-fs": "~0.4.1",
"mime": "^2.3.1", "mime": "^2.3.1",
"path-is-absolute": "^1.0.0",
"range-parser": "^1.0.3", "range-parser": "^1.0.3",
"url-join": "^4.0.0",
"webpack-log": "^2.0.0" "webpack-log": "^2.0.0"
} }
}, },
"webpack-dev-server": { "webpack-dev-server": {
"version": "3.1.8", "version": "3.1.14",
"resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.1.8.tgz", "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.1.14.tgz",
"integrity": "sha512-c+tcJtDqnPdxCAzEEZKdIPmg3i5i7cAHe+B+0xFNK0BlCc2HF/unYccbU7xTgfGc5xxhCztCQzFmsqim+KhI+A==", "integrity": "sha512-mGXDgz5SlTxcF3hUpfC8hrQ11yhAttuUQWf1Wmb+6zo3x6rb7b9mIfuQvAPLdfDRCGRGvakBWHdHOa0I9p/EVQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"ansi-html": "0.0.7", "ansi-html": "0.0.7",
@ -15064,21 +15012,23 @@
"portfinder": "^1.0.9", "portfinder": "^1.0.9",
"schema-utils": "^1.0.0", "schema-utils": "^1.0.0",
"selfsigned": "^1.9.1", "selfsigned": "^1.9.1",
"semver": "^5.6.0",
"serve-index": "^1.7.2", "serve-index": "^1.7.2",
"sockjs": "0.3.19", "sockjs": "0.3.19",
"sockjs-client": "1.1.5", "sockjs-client": "1.3.0",
"spdy": "^3.4.1", "spdy": "^4.0.0",
"strip-ansi": "^3.0.0", "strip-ansi": "^3.0.0",
"supports-color": "^5.1.0", "supports-color": "^5.1.0",
"webpack-dev-middleware": "3.2.0", "url": "^0.11.0",
"webpack-dev-middleware": "3.4.0",
"webpack-log": "^2.0.0", "webpack-log": "^2.0.0",
"yargs": "12.0.2" "yargs": "12.0.2"
}, },
"dependencies": { "dependencies": {
"ajv": { "ajv": {
"version": "6.5.3", "version": "6.9.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz",
"integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==", "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==",
"dev": true, "dev": true,
"requires": { "requires": {
"fast-deep-equal": "^2.0.1", "fast-deep-equal": "^2.0.1",
@ -15088,9 +15038,9 @@
} }
}, },
"ajv-keywords": { "ajv-keywords": {
"version": "3.2.0", "version": "3.4.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz",
"integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==",
"dev": true "dev": true
}, },
"ansi-regex": { "ansi-regex": {
@ -15122,6 +15072,21 @@
"rimraf": "^2.2.8" "rimraf": "^2.2.8"
} }
}, },
"execa": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
"integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
"dev": true,
"requires": {
"cross-spawn": "^6.0.0",
"get-stream": "^4.0.0",
"is-stream": "^1.1.0",
"npm-run-path": "^2.0.0",
"p-finally": "^1.0.0",
"signal-exit": "^3.0.0",
"strip-eof": "^1.0.0"
}
},
"fast-deep-equal": { "fast-deep-equal": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
@ -15137,6 +15102,15 @@
"locate-path": "^3.0.0" "locate-path": "^3.0.0"
} }
}, },
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
"dev": true,
"requires": {
"pump": "^3.0.0"
}
},
"globby": { "globby": {
"version": "6.1.0", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
@ -15200,31 +15174,31 @@
} }
}, },
"mem": { "mem": {
"version": "4.0.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/mem/-/mem-4.0.0.tgz", "resolved": "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz",
"integrity": "sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA==", "integrity": "sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==",
"dev": true, "dev": true,
"requires": { "requires": {
"map-age-cleaner": "^0.1.1", "map-age-cleaner": "^0.1.1",
"mimic-fn": "^1.0.0", "mimic-fn": "^1.0.0",
"p-is-promise": "^1.1.0" "p-is-promise": "^2.0.0"
} }
}, },
"os-locale": { "os-locale": {
"version": "3.0.1", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.0.1.tgz", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
"integrity": "sha512-7g5e7dmXPtzcP4bgsZ8ixDVqA7oWYuEz4lOSujeWyliPai4gfVDiFIcwBg3aGCPnmSGfzOKTK3ccPn0CKv3DBw==", "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
"dev": true, "dev": true,
"requires": { "requires": {
"execa": "^0.10.0", "execa": "^1.0.0",
"lcid": "^2.0.0", "lcid": "^2.0.0",
"mem": "^4.0.0" "mem": "^4.0.0"
} }
}, },
"p-limit": { "p-limit": {
"version": "2.0.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz",
"integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==", "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==",
"dev": true, "dev": true,
"requires": { "requires": {
"p-try": "^2.0.0" "p-try": "^2.0.0"
@ -15254,6 +15228,16 @@
"find-up": "^3.0.0" "find-up": "^3.0.0"
} }
}, },
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"schema-utils": { "schema-utils": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
@ -15265,6 +15249,12 @@
"ajv-keywords": "^3.1.0" "ajv-keywords": "^3.1.0"
} }
}, },
"semver": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
"integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==",
"dev": true
},
"strip-ansi": { "strip-ansi": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
@ -15358,6 +15348,11 @@
"integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
"dev": true "dev": true
}, },
"webstomp-client": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/webstomp-client/-/webstomp-client-1.2.6.tgz",
"integrity": "sha512-9HajO6Ki2ViEGIusLZtjM2lcO2VaQUvtXhLQQ4Cm543RLjfTCEgI3sFaiXts3TvfZgrtY/vI/+qUkm2qWD/NVg=="
},
"whatwg-encoding": { "whatwg-encoding": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.4.tgz", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.4.tgz",

View File

@ -21,7 +21,8 @@
"vue-bootstrap-datetimepicker": "^5.0.1", "vue-bootstrap-datetimepicker": "^5.0.1",
"vue-chartjs": "^3.4.0", "vue-chartjs": "^3.4.0",
"vue-router": "^3.0.1", "vue-router": "^3.0.1",
"vuex": "^3.0.1" "vuex": "^3.0.1",
"webstomp-client": "^1.2.6"
}, },
"devDependencies": { "devDependencies": {
"@vue/cli-plugin-babel": "^3.0.3", "@vue/cli-plugin-babel": "^3.0.3",

View File

@ -10,6 +10,7 @@ const ViewObservations = () => import("./views/ViewObservations.vue");
const ObservationComplete = () => import("./views/ObservationComplete.vue"); const ObservationComplete = () => import("./views/ObservationComplete.vue");
const DBError = () => import("./views/DatabaseUnavailable.vue"); const DBError = () => import("./views/DatabaseUnavailable.vue");
const About = () => import("./views/About.vue"); const About = () => import("./views/About.vue");
const GroupSession = () => import("./views/GroupSession.vue")
Vue.use(Router); Vue.use(Router);
@ -64,6 +65,11 @@ export default new Router({
path: "/about", path: "/about",
name: "about", name: "about",
component: About component: About
},
{
path: "/groupsession",
name: "groupsession",
component: GroupSession
} }
] ]
}); });

View File

@ -0,0 +1,32 @@
<template>
</template>
<script>
import webstomp from 'webstomp-client'
import SockJS from "sockjs-client"
export default {
name: "groupsession",
title: "Group Session",
data: function() {
return {
stompclient: null,
data: []
}
},
mounted() {
console.log("loading")
this.stompclient = webstomp.over(new SockJS('/websocket', {heartbeat: false}))
var self = this
this.stompclient.connect([], function() {
self.stompclient.subscribe("/ws/observations", function (incomingData) {
self.data.push(incomingData)
})
})
},
beforeDestroy() {
if(this.stompclient != null){
this.stompclient.disconnect()
}
}
}
</script>

View File

@ -20,6 +20,11 @@
<b-button class="scale-in-center" size="lg" to="/stats" block><v-icon name="chart-line"/> View daily observation statistics</b-button> <b-button class="scale-in-center" size="lg" to="/stats" block><v-icon name="chart-line"/> View daily observation statistics</b-button>
</b-col> </b-col>
</b-row> </b-row>
<b-row class="my-3" align-h="center">
<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-col>
</b-row>
</b-container> </b-container>
</template> </template>
@ -28,6 +33,7 @@ import "vue-awesome/icons/file-alt";
import "vue-awesome/icons/th-list"; import "vue-awesome/icons/th-list";
import "vue-awesome/icons/chart-line"; import "vue-awesome/icons/chart-line";
import "vue-awesome/icons/user-check"; import "vue-awesome/icons/user-check";
import "vue-awesome/icons/users"
export default { export default {
name: "Home", name: "Home",
title: "Observations Database" title: "Observations Database"