Linter conformance

This commit is contained in:
neviyn 2019-07-25 15:16:52 +01:00
parent 5154820325
commit 7b34c5c9ba
19 changed files with 1137 additions and 616 deletions

View File

@ -178,7 +178,7 @@ class GroupSessionController {
observations.add(observation) observations.add(observation)
} }
GroupSessionManager.invalidate() GroupSessionManager.invalidate()
if(this::environment.isInitialized && environment.getProperty("smtp.autosendoncomplete")!!.toBoolean()) if (this::environment.isInitialized && environment.getProperty("smtp.autosendoncomplete")!!.toBoolean())
GlobalScope.launch { GlobalScope.launch {
if (::mailer.isInitialized) if (::mailer.isInitialized)
mailer.sendObservationData(observations) mailer.sendObservationData(observations)

View File

@ -54,7 +54,6 @@ class ObservationsController {
@Autowired @Autowired
lateinit var mailer: Email lateinit var mailer: Email
/** /**
* Returns a list of all current sites. * Returns a list of all current sites.
*/ */
@ -285,12 +284,11 @@ class ObservationsController {
logger.info("Sending Observation data by email") logger.info("Sending Observation data by email")
if (::mailer.isInitialized) { if (::mailer.isInitialized) {
val data = getObservations(observationsRequest) val data = getObservations(observationsRequest)
if(data.isEmpty()) if (data.isEmpty())
return false return false
mailer.sendObservationData(data) mailer.sendObservationData(data)
return true return true
} } else
else
logger.error("Mailer has not been initialized.") logger.error("Mailer has not been initialized.")
return false return false
} }

View File

@ -1,28 +1,28 @@
<template> <template>
<div id="app"> <div id="app">
<b-navbar toggleable="md" type="dark" variant="info"> <b-navbar toggleable="md" type="dark" variant="info">
<b-navbar-toggle target="nav_collapse"></b-navbar-toggle> <b-navbar-toggle target="nav_collapse"></b-navbar-toggle>
<b-navbar-brand to="/">Observation Database</b-navbar-brand> <b-navbar-brand to="/">Observation Database</b-navbar-brand>
<b-collapse is-nav id="nav_collapse"> <b-collapse is-nav id="nav_collapse">
<b-navbar-nav> <b-navbar-nav>
<b-nav-item to="/new">New Observation</b-nav-item> <b-nav-item to="/new">New Observation</b-nav-item>
<b-nav-item to="/observations">View Observations</b-nav-item> <b-nav-item to="/observations">View Observations</b-nav-item>
<b-nav-item to="/stats">Graphs</b-nav-item> <b-nav-item to="/stats">Graphs</b-nav-item>
</b-navbar-nav> </b-navbar-nav>
<!-- Right aligned nav items --> <!-- Right aligned nav items -->
<b-navbar-nav class="ml-auto"> <b-navbar-nav class="ml-auto">
<b-nav-item-dropdown text="Admin" right> <b-nav-item-dropdown text="Admin" right>
<b-dropdown-item to="/newsite">New Site</b-dropdown-item> <b-dropdown-item to="/newsite">New Site</b-dropdown-item>
<b-dropdown-item to="/newtutor">New Tutor</b-dropdown-item> <b-dropdown-item to="/newtutor">New Tutor</b-dropdown-item>
</b-nav-item-dropdown> </b-nav-item-dropdown>
</b-navbar-nav> </b-navbar-nav>
</b-collapse> </b-collapse>
</b-navbar> </b-navbar>
<br/> <br />
<transition name="fade" mode="out-in" appear> <transition name="fade" mode="out-in" appear>
<router-view/> <router-view />
</transition> </transition>
</div> </div>
</template> </template>
<!--suppress CssUnusedSymbol --> <!--suppress CssUnusedSymbol -->

View File

@ -3,7 +3,9 @@
<b-row> <b-row>
<b-col cols="3"> <b-col cols="3">
<p>{{ description }}</p> <p>{{ description }}</p>
<h4 v-bind:class="{ scorewarn: scenariofundamental.rating < 3 }">{{ scenariofundamental.rating }}</h4> <h4 v-bind:class="{ scorewarn: scenariofundamental.rating < 3 }">
{{ scenariofundamental.rating }}
</h4>
</b-col> </b-col>
<b-col cols="9"> <b-col cols="9">
<b-form-textarea <b-form-textarea

View File

@ -2,12 +2,20 @@
<b-row> <b-row>
<b-col> <b-col>
<b-form-group label="Site"> <b-form-group label="Site">
<b-form-select class="text-center" v-model="siteSelection" :options="siteOptions"/> <b-form-select
class="text-center"
v-model="siteSelection"
:options="siteOptions"
/>
</b-form-group> </b-form-group>
</b-col> </b-col>
<b-col> <b-col>
<b-form-group label="Tutor"> <b-form-group label="Tutor">
<b-form-select class="text-center" v-model="tutorSelection" :options="tutorOptions"/> <b-form-select
class="text-center"
v-model="tutorSelection"
:options="tutorOptions"
/>
</b-form-group> </b-form-group>
</b-col> </b-col>
<!-- <!--
@ -19,7 +27,11 @@
--> -->
<b-col> <b-col>
<b-form-group label="Person"> <b-form-group label="Person">
<b-form-input v-model="person" type="text" class="text-center"></b-form-input> <b-form-input
v-model="person"
type="text"
class="text-center"
></b-form-input>
</b-form-group> </b-form-group>
</b-col> </b-col>
<b-col> <b-col>
@ -156,7 +168,7 @@ export default {
this.$refs.errorModal.show(); this.$refs.errorModal.show();
}); });
this.getTutors(); this.getTutors();
this.$emit('refresh'); this.$emit("refresh");
} }
}; };
</script> </script>

View File

@ -33,7 +33,6 @@ export default {
}; };
</script> </script>
<style> <style>
.btn-1 { .btn-1 {
color: #ffffff; color: #ffffff;

View File

@ -10,8 +10,8 @@ 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") const GroupSession = () => import("./views/GroupSession.vue");
const GroupSessionInput = () => import("./views/GroupSessionInput.vue") const GroupSessionInput = () => import("./views/GroupSessionInput.vue");
Vue.use(Router); Vue.use(Router);

View File

@ -1,24 +1,36 @@
<template> <template>
<b-container> <b-container>
<b-row> <b-row>
<b-col> <b-col>
<h1 class="display-4 focus-in-expand-fwd">Training Observations Database</h1> <h1 class="display-4 focus-in-expand-fwd">
</b-col> Training Observations Database
</b-row> </h1>
<br/> </b-col>
<b-row> </b-row>
<b-col> <br />
<v-icon name="crown" scale="2" class="mb-3 jello-horizontal"></v-icon><p class="lead">Created by Nathan Cannon&nbsp; <b-row>
<a href="mailto:nathan.cannon@edf-energy.com"><v-icon name="briefcase"></v-icon></a>&nbsp; <b-col>
<a href="mailto:neviynhd@gmail.com"><v-icon name="home"></v-icon></a></p> <v-icon name="crown" scale="2" class="mb-3 jello-horizontal"></v-icon>
</b-col> <p class="lead">
</b-row> Created by Nathan Cannon&nbsp;
<b-row> <a href="mailto:nathan.cannon@edf-energy.com"
<b-col> ><v-icon name="briefcase"></v-icon></a
<v-icon name="power-off" scale="2" class="mb-3 jello-horizontal"></v-icon><p class="lead">Powered by Spring Boot and Vue.js</p> >&nbsp;
</b-col> <a href="mailto:neviynhd@gmail.com"><v-icon name="home"></v-icon></a>
</b-row> </p>
</b-container> </b-col>
</b-row>
<b-row>
<b-col>
<v-icon
name="power-off"
scale="2"
class="mb-3 jello-horizontal"
></v-icon>
<p class="lead">Powered by Spring Boot and Vue.js</p>
</b-col>
</b-row>
</b-container>
</template> </template>
<script> <script>

View File

@ -1,25 +1,30 @@
<template> <template>
<b-container> <b-container>
<b-row class="my-3"> <b-row class="my-3">
<b-col> <b-col>
<v-icon name="desktop" style="color: black" scale="5"></v-icon> <v-icon name="desktop" style="color: black" scale="5"></v-icon>
<v-icon class="mx-5 heartbeat" name="unlink" style="color: black" scale="4"></v-icon> <v-icon
<v-icon name="database" style="color: black" scale="5"></v-icon> class="mx-5 heartbeat"
</b-col> name="unlink"
</b-row> style="color: black"
<br/> scale="4"
<b-row class="my-3"> ></v-icon>
<b-col> <v-icon name="database" style="color: black" scale="5"></v-icon>
<h1>Database Unavailable</h1> </b-col>
</b-col> </b-row>
</b-row> <br />
<b-row> <b-row class="my-3">
<b-col class="text-center"> <b-col>
<p>The database is currently unavailable.</p> <h1>Database Unavailable</h1>
<p>Try again later or contact your System Administrator.</p> </b-col>
</b-col> </b-row>
</b-row> <b-row>
</b-container> <b-col class="text-center">
<p>The database is currently unavailable.</p>
<p>Try again later or contact your System Administrator.</p>
</b-col>
</b-row>
</b-container>
</template> </template>
<script> <script>

View File

@ -3,14 +3,19 @@
<b-row v-if="active"> <b-row v-if="active">
<b-col cols="12" md="3"> <b-col cols="12" md="3">
<vue-qrcode v-model="qrdata" :options="{ width: 250 }"></vue-qrcode> <vue-qrcode v-model="qrdata" :options="{ width: 250 }"></vue-qrcode>
<p>Scan the code or navigate to <p>
<br> Scan the code or navigate to
<br />
{{ qrdata }} {{ qrdata }}
</p> </p>
</b-col> </b-col>
<b-col cols="12" md="9"> <b-col cols="12" md="9">
<b-card-group v-for="(item, index) in data" v-bind:key="index"> <b-card-group v-for="(item, index) in data" v-bind:key="index">
<b-card border-variant="secondary" header-border-variant="secondary" :header="index"> <b-card
border-variant="secondary"
header-border-variant="secondary"
:header="index"
>
<b-card-text> <b-card-text>
<b-table :fields="tableFields" :items="item"></b-table> <b-table :fields="tableFields" :items="item"></b-table>
</b-card-text> </b-card-text>
@ -18,7 +23,9 @@
</b-card-group> </b-card-group>
</b-col> </b-col>
<b-col> <b-col>
<b-button size="lg" variant="primary" v-on:click="showCompletionModal()">Finish Session</b-button> <b-button size="lg" variant="primary" v-on:click="showCompletionModal()"
>Finish Session</b-button
>
</b-col> </b-col>
</b-row> </b-row>
<b-row v-else-if="complete"> <b-row v-else-if="complete">
@ -30,7 +37,9 @@
</b-row> </b-row>
<b-row> <b-row>
<b-col> <b-col>
<p>Observation data for this session is now saved in the database.</p> <p>
Observation data for this session is now saved in the database.
</p>
</b-col> </b-col>
</b-row> </b-row>
<b-row> <b-row>
@ -39,7 +48,8 @@
size="lg" size="lg"
variant="primary" variant="primary"
v-on:click="window.location.reload()" v-on:click="window.location.reload()"
>Start a New Session</b-button> >Start a New Session</b-button
>
</b-col> </b-col>
</b-row> </b-row>
</b-col> </b-col>
@ -62,7 +72,11 @@
<b-row align-h="center"> <b-row align-h="center">
<b-col> <b-col>
<b-form-group label="Type"> <b-form-group label="Type">
<b-form-select v-model="type" style="text-align:center;" required> <b-form-select
v-model="type"
style="text-align:center;"
required
>
<option :value="null">Select a training type</option> <option :value="null">Select a training type</option>
<option value="INITIAL">INITIAL</option> <option value="INITIAL">INITIAL</option>
<option value="CONTINUING">CONTINUING</option> <option value="CONTINUING">CONTINUING</option>
@ -74,7 +88,10 @@
<b-col> <b-col>
<b-form-group label="Tutor(s)"> <b-form-group label="Tutor(s)">
<p v-if="site == null">Select a site first.</p> <p v-if="site == null">Select a site first.</p>
<b-form-checkbox-group v-model="tutors" :options="tutorOptions"></b-form-checkbox-group> <b-form-checkbox-group
v-model="tutors"
:options="tutorOptions"
></b-form-checkbox-group>
</b-form-group> </b-form-group>
</b-col> </b-col>
</b-row> </b-row>
@ -92,7 +109,10 @@
></b-form-input> ></b-form-input>
</b-col> </b-col>
<b-col cols="1"> <b-col cols="1">
<b-button v-on:click="scenarioTitles.splice(index, 1)" variant="danger"> <b-button
v-on:click="scenarioTitles.splice(index, 1)"
variant="danger"
>
<b>Delete</b> <b>Delete</b>
</b-button> </b-button>
</b-col> </b-col>
@ -100,27 +120,31 @@
<b-row align-h="center"> <b-row align-h="center">
<b-col> <b-col>
<b-button <b-button
v-on:click="scenarioTitles.push({data:''})" v-on:click="scenarioTitles.push({ data: '' })"
size="lg" size="lg"
variant="primary" variant="primary"
>Add Another Scenario</b-button> >Add Another Scenario</b-button
>
</b-col> </b-col>
</b-row> </b-row>
<b-row> <b-row>
<b-col> <b-col>
<br> <br />
</b-col> </b-col>
</b-row> </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 <b-button
size="lg" size="lg"
variant="secondary" variant="secondary"
v-on:click="connectToPrevious()" v-on:click="connectToPrevious()"
>Connect to Previous Session</b-button> >Connect to Previous Session</b-button
>
</b-col> </b-col>
</b-row> </b-row>
</b-form> </b-form>
@ -134,7 +158,11 @@
@shown="clearPassword" @shown="clearPassword"
> >
<form @submit.stop.prevent="handleSubmit"> <form @submit.stop.prevent="handleSubmit">
<b-form-input type="password" placeholder="Enter password" v-model="submitPassword"></b-form-input> <b-form-input
type="password"
placeholder="Enter password"
v-model="submitPassword"
></b-form-input>
</form> </form>
</b-modal> </b-modal>
<b-modal <b-modal
@ -145,7 +173,11 @@
@shown="clearPassword" @shown="clearPassword"
> >
<form @submit.stop.prevent="handleSubmit"> <form @submit.stop.prevent="handleSubmit">
<b-form-input type="password" placeholder="Enter password" v-model="submitPassword"></b-form-input> <b-form-input
type="password"
placeholder="Enter password"
v-model="submitPassword"
></b-form-input>
</form> </form>
</b-modal> </b-modal>
</b-container> </b-container>
@ -196,7 +228,6 @@ export default {
} }
}, },
mounted() { mounted() {
console.log("loading");
Vue.axios Vue.axios
.get("/site") .get("/site")
.then(response => { .then(response => {
@ -218,12 +249,6 @@ export default {
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",
@ -236,15 +261,12 @@ export default {
axiosConfig axiosConfig
) )
.then(function(response) { .then(function(response) {
console.log(response); if (!("error" in response.data)) {
if ("error" in response.data) {
} else {
self.setupSession(response.data); self.setupSession(response.data);
} }
}) })
.catch(function(error) { .catch(function() {
self.active = false; self.active = false;
console.log(error);
}); });
}, },
connectToPrevious: function() { connectToPrevious: function() {
@ -252,9 +274,7 @@ export default {
Vue.axios Vue.axios
.get("/grpob/recover") .get("/grpob/recover")
.then(function(response) { .then(function(response) {
console.log(response); if (!("error" in response.data)) {
if ("error" in response.data) {
} else {
self.setupSession(response.data); self.setupSession(response.data);
} }
}) })
@ -266,8 +286,6 @@ export default {
}); });
}, },
setupSession: function(rdata) { setupSession: function(rdata) {
console.log("rdata");
console.log(rdata);
var self = this; var self = this;
self.qrdata = `http://${rdata.ip}:${rdata.port}/#/groupsession/${ self.qrdata = `http://${rdata.ip}:${rdata.port}/#/groupsession/${
rdata.id rdata.id
@ -340,14 +358,10 @@ export default {
Vue.axios Vue.axios
.post("/grpob/complete", {}, axiosConfig) .post("/grpob/complete", {}, axiosConfig)
.then(function(response) { .then(function(response) {
console.log(response.data);
if ("success" in response.data) { if ("success" in response.data) {
self.complete = true; self.complete = true;
self.active = false; self.active = false;
} }
})
.catch(function(error) {
console.log(error);
}); });
} }
} }

View File

@ -8,13 +8,18 @@
<b-container v-else-if="complete"> <b-container v-else-if="complete">
<h2>Submission Complete</h2> <h2>Submission Complete</h2>
<p>Thank you.</p> <p>Thank you.</p>
<p>This observation session is now closed and your data submitted to the database.</p> <p>
This observation session is now closed and your data submitted to the
database.
</p>
</b-container> </b-container>
<b-container v-else-if="!valid"> <b-container v-else-if="!valid">
<p>Getting session data from server</p> <p>Getting session data from server</p>
</b-container> </b-container>
<b-container v-else-if="scenarios.length === 0"> <b-container v-else-if="scenarios.length === 0">
<p>No scenarios defined for this session, please setup a new group session</p> <p>
No scenarios defined for this session, please setup a new group session
</p>
</b-container> </b-container>
<b-container v-else fluid> <b-container v-else fluid>
<b-form> <b-form>
@ -31,15 +36,22 @@
</b-form-group> </b-form-group>
</b-col> </b-col>
<b-col> <b-col>
<b-button v-on:click="attemptReconnect()">Reconnect <b-button v-on:click="attemptReconnect()">Reconnect </b-button>
</b-button>
</b-col> </b-col>
</b-row> </b-row>
<b-row v-for="(item, index) in scenarios" v-bind:key="index" class="border bottom-buffer"> <b-row
v-for="(item, index) in scenarios"
v-bind:key="index"
class="border bottom-buffer"
>
<b-col> <b-col>
<b-row> <b-row>
<b-col> <b-col>
<b-form-input v-model="item.title" type="text" readonly></b-form-input> <b-form-input
v-model="item.title"
type="text"
readonly
></b-form-input>
</b-col> </b-col>
</b-row> </b-row>
<b-row> <b-row>
@ -49,7 +61,10 @@
<h5>Monitoring</h5> <h5>Monitoring</h5>
<score-selector <score-selector
:score-value="item.monitoring.rating" :score-value="item.monitoring.rating"
v-on:newselection="item.monitoring.rating = $event; actuallySubmit()" v-on:newselection="
item.monitoring.rating = $event;
actuallySubmit();
"
></score-selector> ></score-selector>
</b-col> </b-col>
</b-row> </b-row>
@ -80,7 +95,10 @@
<h5>Control Procedural</h5> <h5>Control Procedural</h5>
<score-selector <score-selector
:score-value="item.controlProcedural.rating" :score-value="item.controlProcedural.rating"
v-on:newselection="item.controlProcedural.rating = $event; actuallySubmit()" v-on:newselection="
item.controlProcedural.rating = $event;
actuallySubmit();
"
></score-selector> ></score-selector>
</b-col> </b-col>
</b-row> </b-row>
@ -111,7 +129,10 @@
<h5>Control</h5> <h5>Control</h5>
<score-selector <score-selector
:score-value="item.control.rating" :score-value="item.control.rating"
v-on:newselection="item.control.rating = $event; actuallySubmit()" v-on:newselection="
item.control.rating = $event;
actuallySubmit();
"
></score-selector> ></score-selector>
</b-col> </b-col>
</b-row> </b-row>
@ -142,7 +163,10 @@
<h5>Conservatism</h5> <h5>Conservatism</h5>
<score-selector <score-selector
:score-value="item.conservatism.rating" :score-value="item.conservatism.rating"
v-on:newselection="item.conservatism.rating = $event; actuallySubmit()" v-on:newselection="
item.conservatism.rating = $event;
actuallySubmit();
"
></score-selector> ></score-selector>
</b-col> </b-col>
</b-row> </b-row>
@ -173,7 +197,10 @@
<h5>Teamwork Communications</h5> <h5>Teamwork Communications</h5>
<score-selector <score-selector
:score-value="item.teamworkCommunications.rating" :score-value="item.teamworkCommunications.rating"
v-on:newselection="item.teamworkCommunications.rating = $event; actuallySubmit()" v-on:newselection="
item.teamworkCommunications.rating = $event;
actuallySubmit();
"
></score-selector> ></score-selector>
</b-col> </b-col>
</b-row> </b-row>
@ -204,7 +231,10 @@
<h5>Teamwork Leadership</h5> <h5>Teamwork Leadership</h5>
<score-selector <score-selector
:score-value="item.teamworkLeadership.rating" :score-value="item.teamworkLeadership.rating"
v-on:newselection="item.teamworkLeadership.rating = $event; actuallySubmit()" v-on:newselection="
item.teamworkLeadership.rating = $event;
actuallySubmit();
"
></score-selector> ></score-selector>
</b-col> </b-col>
</b-row> </b-row>
@ -235,7 +265,10 @@
<h5>Teamwork Workload</h5> <h5>Teamwork Workload</h5>
<score-selector <score-selector
:score-value="item.teamworkWorkload.rating" :score-value="item.teamworkWorkload.rating"
v-on:newselection="item.teamworkWorkload.rating = $event; actuallySubmit()" v-on:newselection="
item.teamworkWorkload.rating = $event;
actuallySubmit();
"
></score-selector> ></score-selector>
</b-col> </b-col>
</b-row> </b-row>
@ -266,7 +299,10 @@
<h5>Knowledge</h5> <h5>Knowledge</h5>
<score-selector <score-selector
:score-value="item.knowledge.rating" :score-value="item.knowledge.rating"
v-on:newselection="item.knowledge.rating = $event; actuallySubmit()" v-on:newselection="
item.knowledge.rating = $event;
actuallySubmit();
"
></score-selector> ></score-selector>
</b-col> </b-col>
</b-row> </b-row>
@ -294,8 +330,10 @@
</b-row> </b-row>
</b-col> </b-col>
</b-row> </b-row>
<br> <br />
<b-button variant="primary" v-on:click="actuallySubmit()">Update</b-button> <b-button variant="primary" v-on:click="actuallySubmit()"
>Update</b-button
>
</b-form> </b-form>
</b-container> </b-container>
</b-container> </b-container>
@ -331,7 +369,7 @@ export default {
self.addAnotherObservation(x); self.addAnotherObservation(x);
}); });
self.valid = true; self.valid = true;
self.setupSession() self.setupSession();
} }
}) })
.catch(function(error) { .catch(function(error) {
@ -340,7 +378,6 @@ export default {
return; return;
} }
self.error = error.response; self.error = error.response;
console.log(error);
}); });
} }
}, },
@ -396,15 +433,9 @@ export default {
person: self.participant, person: self.participant,
scenarios: self.scenarios scenarios: self.scenarios
}; };
Vue.axios Vue.axios.post("/grpob/submit", payload).catch(function(error) {
.post("/grpob/submit", payload) self.error = error;
.then(function(response) { });
console.log(response);
})
.catch(function(error) {
self.error = error;
console.log(error);
});
}, },
setupSession: function() { setupSession: function() {
var self = this; var self = this;
@ -418,20 +449,18 @@ export default {
var data = JSON.parse(incomingData.body); var data = JSON.parse(incomingData.body);
if (data.status === "complete") { if (data.status === "complete") {
self.complete = true; self.complete = true;
self.stompclient.disconnect() self.stompclient.disconnect();
} }
}); });
}); });
}, },
attemptReconnect: function() { attemptReconnect: function() {
var self = this; var self = this;
Vue.axios.get(`/grpob/participant/${self.participant}`) Vue.axios
.then(function(response){ .get(`/grpob/participant/${self.participant}`)
self.scenarios = response.data; .then(function(response) {
}) self.scenarios = response.data;
.catch(function(error){ });
console.log(error)
})
} }
} }
}; };

View File

@ -1,31 +1,48 @@
<template> <template>
<b-container> <b-container>
<b-row> <b-row>
<b-col> <b-col>
<h1 class="tracking-in-expand-fwd display-4"><v-icon name="user-check" scale="2"></v-icon> Training Observations Database</h1> <h1 class="tracking-in-expand-fwd display-4">
</b-col> <v-icon name="user-check" scale="2"></v-icon> Training Observations
</b-row> Database
<b-row class="my-3" align-h="center"> </h1>
<b-col lg="6" sm="12"> </b-col>
<b-button class="scale-in-center" size="lg" to="/new" variant="primary" block><v-icon name="file-alt"/> Start a new observation</b-button> </b-row>
</b-col> <b-row class="my-3" align-h="center">
</b-row> <b-col lg="6" sm="12">
<b-row class="my-3" align-h="center"> <b-button
<b-col lg="6" sm="12"> class="scale-in-center"
<b-button class="scale-in-center" size="lg" to="/observations" block><v-icon name="th-list"/> Read past observations</b-button> size="lg"
</b-col> to="/new"
</b-row> variant="primary"
<b-row class="my-3" align-h="center"> block
<b-col lg="6" sm="12"> ><v-icon name="file-alt" /> Start a new observation</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-row class="my-3" align-h="center">
<b-col lg="6" sm="12"> <b-col lg="6" sm="12">
<b-button class="scale-in-center" size="lg" to="/groupsession" block><v-icon name="users"/> Start a Group Session</b-button> <b-button class="scale-in-center" size="lg" to="/observations" block
</b-col> ><v-icon name="th-list" /> Read past observations</b-button
</b-row> >
</b-container> </b-col>
</b-row>
<b-row class="my-3" align-h="center">
<b-col lg="6" sm="12">
<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-row>
<b-row class="my-3" align-h="center">
<b-col lg="6" sm="12">
<b-button class="scale-in-center" size="lg" to="/groupsession" block
><v-icon name="users" /> Start a Group Session</b-button
>
</b-col>
</b-row>
</b-container>
</template> </template>
<script> <script>
@ -33,7 +50,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" import "vue-awesome/icons/users";
export default { export default {
name: "Home", name: "Home",
title: "Observations Database" title: "Observations Database"

View File

@ -1,21 +1,35 @@
<template> <template>
<b-container> <b-container>
<h2>New Site</h2> <h2>New Site</h2>
<b-form @submit="onSubmit" id="submission-form"> <b-form @submit="onSubmit" id="submission-form">
<b-form-group horizontal label="Site Name"> <b-form-group horizontal label="Site Name">
<b-form-input v-model="siteName" type="text" style="text-align:center;"/> <b-form-input
</b-form-group> v-model="siteName"
<b-form-group horizontal label="Password"> type="text"
<b-form-input v-model="submissionPassword" type="password" style="text-align:center;" /> style="text-align:center;"
</b-form-group> />
<b-button type="submit" size="lg" variant="primary">Submit</b-button> </b-form-group>
</b-form> <b-form-group horizontal label="Password">
<br/> <b-form-input
<b-alert :show="dismissCountDown" dismissible fade :variant="alertVariant" @dismissed="dismissCountDown=0" v-model="submissionPassword"
@dismiss-count-down="countDownChanged"> type="password"
{{ alertText }} style="text-align:center;"
</b-alert> />
</b-container> </b-form-group>
<b-button type="submit" size="lg" variant="primary">Submit</b-button>
</b-form>
<br />
<b-alert
:show="dismissCountDown"
dismissible
fade
:variant="alertVariant"
@dismissed="dismissCountDown = 0"
@dismiss-count-down="countDownChanged"
>
{{ alertText }}
</b-alert>
</b-container>
</template> </template>
<script> <script>
@ -35,17 +49,14 @@ export default {
}; };
}, },
mounted() { mounted() {
Vue.axios Vue.axios.get("/site").catch(error => {
.get("/site") if (error.response.status === 404) {
.then(response => {}) this.$router.push("/dberror");
.catch(error => { return;
if (error.response.status === 404) { }
this.$router.push("/dberror"); this.alertText = error.response.data;
return; this.alertVariant = "danger";
} });
this.alertText = error.response.data;
this.alertVariant = "danger";
});
}, },
methods: { methods: {
countDownChanged: function(dismissCountDown) { countDownChanged: function(dismissCountDown) {
@ -72,11 +83,10 @@ export default {
this.alertText = "Successfully added " + response.data.text; this.alertText = "Successfully added " + response.data.text;
this.showAlert(); this.showAlert();
}) })
.catch(error => { .catch(() => {
this.alertVariant = "danger"; this.alertVariant = "danger";
this.alertText = "Failed to add Site"; this.alertText = "Failed to add Site";
this.showAlert(); this.showAlert();
console.log(error);
}); });
} }
} }

View File

@ -3,18 +3,37 @@
<h2>New Tutor</h2> <h2>New Tutor</h2>
<b-form @submit="onSubmit" id="submission-form"> <b-form @submit="onSubmit" id="submission-form">
<b-form-group horizontal label="Site"> <b-form-group horizontal label="Site">
<b-form-select v-model="siteSelection" :options="siteOptions" style="text-align:center;" /> <b-form-select
v-model="siteSelection"
:options="siteOptions"
style="text-align:center;"
/>
</b-form-group> </b-form-group>
<b-form-group horizontal label="Tutor Name"> <b-form-group horizontal label="Tutor Name">
<b-form-input v-model="tutorName" type="text" style="text-align:center;" /> <b-form-input
v-model="tutorName"
type="text"
style="text-align:center;"
/>
</b-form-group> </b-form-group>
<b-form-group horizontal label="Password"> <b-form-group horizontal label="Password">
<b-form-input v-model="submissionPassword" type="password" style="text-align:center;" /> <b-form-input
v-model="submissionPassword"
type="password"
style="text-align:center;"
/>
</b-form-group> </b-form-group>
<b-button type="submit" size="lg" variant="primary">Submit</b-button> <b-button type="submit" size="lg" variant="primary">Submit</b-button>
</b-form> </b-form>
<br /> <br />
<b-alert :show="dismissCountDown" dismissible fade :variant="alertVariant" @dismissed="dismissCountDown=0" @dismiss-count-down="countDownChanged"> <b-alert
:show="dismissCountDown"
dismissible
fade
:variant="alertVariant"
@dismissed="dismissCountDown = 0"
@dismiss-count-down="countDownChanged"
>
{{ alertText }} {{ alertText }}
</b-alert> </b-alert>
</b-container> </b-container>
@ -84,11 +103,10 @@ export default {
this.alertText = "Successfully added " + response.data.text; this.alertText = "Successfully added " + response.data.text;
this.showAlert(); this.showAlert();
}) })
.catch(error => { .catch(() => {
this.alertVariant = "danger"; this.alertVariant = "danger";
this.alertText = "Failed to add Tutor"; this.alertText = "Failed to add Tutor";
this.showAlert(); this.showAlert();
console.log(error);
}); });
} }
} }

View File

@ -1,211 +1,463 @@
<template> <template>
<b-container fluid> <b-container fluid>
<b-container v-if="type != null && whom != null && site != null && tutors != null" fluid style="padding-left: 130px;"> <b-container
<h3> v-if="type != null && whom != null && site != null && tutors != null"
<v-icon name="tag" scale="1.5"/> fluid
{{type}}&nbsp;/&nbsp;{{whom}} style="padding-left: 130px;"
</h3> >
<b-container class="sidebar"> <h3>
<b-row align-v="center" class="sidebar-vert-padding" v-if="totals[0] > 0"> <v-icon name="tag" scale="1.5" />
<b-col class="centered-image"> {{ type }}&nbsp;/&nbsp;{{ whom }}
<img src="../assets/Monitoring.svg" class="image-opacity" v-bind:class="{ scorewarning: totals[0] < warningBound }"/> </h3>
<div class="image-centered-text">{{ totals[0] }}</div> <b-container class="sidebar">
</b-col> <b-row
</b-row> align-v="center"
<b-row align-v="center" class="sidebar-vert-padding" v-if="totals[1] > 0"> class="sidebar-vert-padding"
<b-col class="centered-image"> v-if="totals[0] > 0"
<img src="../assets/Control.svg" class="image-opacity" v-bind:class="{ scorewarning: totals[1] < warningBound }"/> >
<div class="image-centered-text">{{ totals[1] }}</div> <b-col class="centered-image">
</b-col> <img
</b-row> src="../assets/Monitoring.svg"
<b-row align-v="center" class="sidebar-vert-padding" v-if="totals[2] > 0"> class="image-opacity"
<b-col class="centered-image"> v-bind:class="{ scorewarning: totals[0] < warningBound }"
<img src="../assets/Control.svg" class="image-opacity" v-bind:class="{ scorewarning: totals[2] < warningBound }"/> />
<div class="image-centered-text">{{ totals[2] }}</div> <div class="image-centered-text">{{ totals[0] }}</div>
</b-col> </b-col>
</b-row> </b-row>
<b-row align-v="center" class="sidebar-vert-padding" v-if="totals[3] > 0"> <b-row
<b-col class="centered-image"> align-v="center"
<img src="../assets/Conservatism.svg" class="image-opacity" v-bind:class="{ scorewarning: totals[3] < warningBound }"/> class="sidebar-vert-padding"
<div class="image-centered-text">{{ totals[3] }}</div> v-if="totals[1] > 0"
</b-col> >
</b-row> <b-col class="centered-image">
<b-row align-v="center" class="sidebar-vert-padding" v-if="totals[4] > 0"> <img
<b-col class="centered-image"> src="../assets/Control.svg"
<img src="../assets/Teamwork.svg" class="image-opacity" v-bind:class="{ scorewarning: totals[4] < warningBound }"/> class="image-opacity"
<div class="image-centered-text">{{ totals[4] }}</div> v-bind:class="{ scorewarning: totals[1] < warningBound }"
</b-col> />
</b-row> <div class="image-centered-text">{{ totals[1] }}</div>
<b-row align-v="center" class="sidebar-vert-padding" v-if="totals[5] > 0"> </b-col>
<b-col class="centered-image"> </b-row>
<img src="../assets/Teamwork.svg" class="image-opacity" v-bind:class="{ scorewarning: totals[5] < warningBound }"/> <b-row
<div class="image-centered-text">{{ totals[5] }}</div> align-v="center"
</b-col> class="sidebar-vert-padding"
</b-row> v-if="totals[2] > 0"
<b-row align-v="center" class="sidebar-vert-padding" v-if="totals[6] > 0"> >
<b-col class="centered-image"> <b-col class="centered-image">
<img src="../assets/Teamwork.svg" class="image-opacity" v-bind:class="{ scorewarning: totals[6] < warningBound }"/> <img
<div class="image-centered-text">{{ totals[6] }}</div> src="../assets/Control.svg"
</b-col> class="image-opacity"
</b-row> v-bind:class="{ scorewarning: totals[2] < warningBound }"
<b-row align-v="center" class="sidebar-vert-padding" v-if="totals[7] > 0"> />
<b-col class="centered-image"> <div class="image-centered-text">{{ totals[2] }}</div>
<img src="../assets/Knowledge.svg" class="image-opacity" v-bind:class="{ scorewarning: totals[7] < warningBound }"/> </b-col>
<div class="image-centered-text">{{ totals[7] }}</div> </b-row>
</b-col> <b-row
</b-row> align-v="center"
</b-container> class="sidebar-vert-padding"
<br /> v-if="totals[3] > 0"
<b-form @submit="onSubmit" id="submission-form" novalidate> >
<b-container v-for="(item, index) in scenarios" v-bind:key="index" class="border bottom-buffer" fluid> <b-col class="centered-image">
<b-row> <img
<b-col> src="../assets/Conservatism.svg"
<b-form-input v-model="item.title" type="text" placeholder="Enter scenario description."></b-form-input> class="image-opacity"
</b-col> v-bind:class="{ scorewarning: totals[3] < warningBound }"
<b-col cols="1"> />
<b-button v-on:click="deleteObservation(index)" variant="danger"><b>Delete</b></b-button> <div class="image-centered-text">{{ totals[3] }}</div>
</b-col> </b-col>
</b-row> </b-row>
<b-row> <b-row
<b-col cols="6" class="border"> align-v="center"
<b-row> class="sidebar-vert-padding"
<b-col cols="4"> v-if="totals[4] > 0"
<h5>Monitoring</h5> >
<score-selector :score-value="item.monitoring.rating" v-on:newselection="item.monitoring.rating = $event; updateTotals();"></score-selector> <b-col class="centered-image">
</b-col> <img
<b-col cols="8"> src="../assets/Teamwork.svg"
<b-form-textarea v-model="item.monitoring.strengths" placeholder="Strengths" :rows="1" :max-rows="2" no-resize class="strength"></b-form-textarea> class="image-opacity"
<b-form-textarea v-model="item.monitoring.improvements" placeholder="AFIs" :rows="1" :max-rows="2" no-resize class="afi"></b-form-textarea> v-bind:class="{ scorewarning: totals[4] < warningBound }"
</b-col> />
</b-row> <div class="image-centered-text">{{ totals[4] }}</div>
</b-col> </b-col>
<b-col cols="6" class="border"> </b-row>
<b-row> <b-row
<b-col cols="4"> align-v="center"
<h5>Control Procedural</h5> class="sidebar-vert-padding"
<score-selector :score-value="item.controlProcedural.rating" v-on:newselection="item.controlProcedural.rating = $event; updateTotals();"></score-selector> v-if="totals[5] > 0"
</b-col> >
<b-col cols="8"> <b-col class="centered-image">
<b-form-textarea v-model="item.controlProcedural.strengths" placeholder="Strengths" :rows="1" :max-rows="2" no-resize class="strength"></b-form-textarea> <img
<b-form-textarea v-model="item.controlProcedural.improvements" placeholder="AFIs" :rows="1" :max-rows="2" no-resize class="afi"></b-form-textarea> src="../assets/Teamwork.svg"
</b-col> class="image-opacity"
</b-row> v-bind:class="{ scorewarning: totals[5] < warningBound }"
</b-col> />
</b-row> <div class="image-centered-text">{{ totals[5] }}</div>
<b-row> </b-col>
<b-col cols="6" class="border"> </b-row>
<b-row> <b-row
<b-col cols="4"> align-v="center"
<h5>Control</h5> class="sidebar-vert-padding"
<score-selector :score-value="item.control.rating" v-on:newselection="item.control.rating = $event; updateTotals();"></score-selector> v-if="totals[6] > 0"
</b-col> >
<b-col cols="8"> <b-col class="centered-image">
<b-form-textarea v-model="item.control.strengths" placeholder="Strengths" :rows="1" :max-rows="2" no-resize class="strength"></b-form-textarea> <img
<b-form-textarea v-model="item.control.improvements" placeholder="AFIs" :rows="1" :max-rows="2" no-resize class="afi"></b-form-textarea> src="../assets/Teamwork.svg"
</b-col> class="image-opacity"
</b-row> v-bind:class="{ scorewarning: totals[6] < warningBound }"
</b-col> />
<b-col cols="6" class="border"> <div class="image-centered-text">{{ totals[6] }}</div>
<b-row> </b-col>
<b-col cols="4"> </b-row>
<h5>Conservatism</h5> <b-row
<score-selector :score-value="item.conservatism.rating" v-on:newselection="item.conservatism.rating = $event; updateTotals();"></score-selector> align-v="center"
</b-col> class="sidebar-vert-padding"
<b-col cols="8"> v-if="totals[7] > 0"
<b-form-textarea v-model="item.conservatism.strengths" placeholder="Strengths" :rows="1" :max-rows="2" no-resize class="strength"></b-form-textarea> >
<b-form-textarea v-model="item.conservatism.improvements" placeholder="AFIs" :rows="1" :max-rows="2" no-resize class="afi"></b-form-textarea> <b-col class="centered-image">
</b-col> <img
</b-row> src="../assets/Knowledge.svg"
</b-col> class="image-opacity"
</b-row> v-bind:class="{ scorewarning: totals[7] < warningBound }"
<b-row> />
<b-col cols="6" class="border"> <div class="image-centered-text">{{ totals[7] }}</div>
<b-row> </b-col>
<b-col cols="4"> </b-row>
<h5>Teamwork Communications</h5> </b-container>
<score-selector :score-value="item.teamworkCommunications.rating" v-on:newselection="item.teamworkCommunications.rating = $event; updateTotals();"></score-selector> <br />
</b-col> <b-form @submit="onSubmit" id="submission-form" novalidate>
<b-col cols="8"> <b-container
<b-form-textarea v-model="item.teamworkCommunications.strengths" placeholder="Strengths" :rows="1" :max-rows="2" no-resize class="strength"></b-form-textarea> v-for="(item, index) in scenarios"
<b-form-textarea v-model="item.teamworkCommunications.improvements" placeholder="AFIs" :rows="1" :max-rows="2" no-resize class="afi"></b-form-textarea> v-bind:key="index"
</b-col> class="border bottom-buffer"
</b-row> fluid
</b-col> >
<b-col cols="6" class="border"> <b-row>
<b-row> <b-col>
<b-col cols="4"> <b-form-input
<h5>Teamwork Leadership</h5> v-model="item.title"
<score-selector :score-value="item.teamworkLeadership.rating" v-on:newselection="item.teamworkLeadership.rating = $event; updateTotals();"></score-selector> type="text"
</b-col> placeholder="Enter scenario description."
<b-col cols="8"> ></b-form-input>
<b-form-textarea v-model="item.teamworkLeadership.strengths" placeholder="Strengths" :rows="1" :max-rows="2" no-resize class="strength"></b-form-textarea> </b-col>
<b-form-textarea v-model="item.teamworkLeadership.improvements" placeholder="AFIs" :rows="1" :max-rows="2" no-resize class="afi"></b-form-textarea> <b-col cols="1">
</b-col> <b-button v-on:click="deleteObservation(index)" variant="danger"
</b-row> ><b>Delete</b></b-button
</b-col> >
</b-row> </b-col>
<b-row> </b-row>
<b-col cols="6" class="border"> <b-row>
<b-row> <b-col cols="6" class="border">
<b-col cols="4"> <b-row>
<h5>Teamwork Workload</h5> <b-col cols="4">
<score-selector :score-value="item.teamworkWorkload.rating" v-on:newselection="item.teamworkWorkload.rating = $event; updateTotals();"></score-selector> <h5>Monitoring</h5>
</b-col> <score-selector
<b-col cols="8"> :score-value="item.monitoring.rating"
<b-form-textarea v-model="item.teamworkWorkload.strengths" placeholder="Strengths" :rows="1" :max-rows="2" no-resize class="strength"></b-form-textarea> v-on:newselection="
<b-form-textarea v-model="item.teamworkWorkload.improvements" placeholder="AFIs" :rows="1" :max-rows="2" no-resize class="afi"></b-form-textarea> item.monitoring.rating = $event;
</b-col> updateTotals();
</b-row> "
</b-col> ></score-selector>
<b-col cols="6" class="border">
<b-row>
<b-col cols="4">
<h5>Knowledge</h5>
<score-selector :score-value="item.knowledge.rating" v-on:newselection="item.knowledge.rating = $event; updateTotals();"></score-selector>
</b-col>
<b-col cols="8">
<b-form-textarea v-model="item.knowledge.strengths" placeholder="Strengths" :rows="1" :max-rows="2" no-resize class="strength"></b-form-textarea>
<b-form-textarea v-model="item.knowledge.improvements" placeholder="AFIs" :rows="1" :max-rows="2" no-resize class="afi"></b-form-textarea>
</b-col>
</b-row>
</b-col>
</b-row>
</b-container>
<b-row align-h="center">
<b-col cols="1">
<b-button type="submit" variant="primary">Submit</b-button>
</b-col>
<b-col offset="1" cols="1">
<b-button v-on:click="this.addAnotherObservation">Add Scenario</b-button>
</b-col>
</b-row>
</b-form>
<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>
<p class="mt-3"><v-icon name="exclamation-circle" scale="1.5" color="gold"/>&nbsp;<i>Leaving this page before submitting will delete all entered data.</i></p>
</b-container>
<b-container v-else>
<b-row>
<b-col>
<h2>Error</h2>
</b-col> </b-col>
</b-row> <b-col cols="8">
<b-row> <b-form-textarea
<b-col> v-model="item.monitoring.strengths"
<p>An Observation session has not been correctly setup, please try again.</p> placeholder="Strengths"
:rows="1"
:max-rows="2"
no-resize
class="strength"
></b-form-textarea>
<b-form-textarea
v-model="item.monitoring.improvements"
placeholder="AFIs"
:rows="1"
:max-rows="2"
no-resize
class="afi"
></b-form-textarea>
</b-col> </b-col>
</b-row> </b-row>
</b-col>
<b-col cols="6" class="border">
<b-row>
<b-col cols="4">
<h5>Control Procedural</h5>
<score-selector
:score-value="item.controlProcedural.rating"
v-on:newselection="
item.controlProcedural.rating = $event;
updateTotals();
"
></score-selector>
</b-col>
<b-col cols="8">
<b-form-textarea
v-model="item.controlProcedural.strengths"
placeholder="Strengths"
:rows="1"
:max-rows="2"
no-resize
class="strength"
></b-form-textarea>
<b-form-textarea
v-model="item.controlProcedural.improvements"
placeholder="AFIs"
:rows="1"
:max-rows="2"
no-resize
class="afi"
></b-form-textarea>
</b-col>
</b-row>
</b-col>
</b-row>
<b-row>
<b-col cols="6" class="border">
<b-row>
<b-col cols="4">
<h5>Control</h5>
<score-selector
:score-value="item.control.rating"
v-on:newselection="
item.control.rating = $event;
updateTotals();
"
></score-selector>
</b-col>
<b-col cols="8">
<b-form-textarea
v-model="item.control.strengths"
placeholder="Strengths"
:rows="1"
:max-rows="2"
no-resize
class="strength"
></b-form-textarea>
<b-form-textarea
v-model="item.control.improvements"
placeholder="AFIs"
:rows="1"
:max-rows="2"
no-resize
class="afi"
></b-form-textarea>
</b-col>
</b-row>
</b-col>
<b-col cols="6" class="border">
<b-row>
<b-col cols="4">
<h5>Conservatism</h5>
<score-selector
:score-value="item.conservatism.rating"
v-on:newselection="
item.conservatism.rating = $event;
updateTotals();
"
></score-selector>
</b-col>
<b-col cols="8">
<b-form-textarea
v-model="item.conservatism.strengths"
placeholder="Strengths"
:rows="1"
:max-rows="2"
no-resize
class="strength"
></b-form-textarea>
<b-form-textarea
v-model="item.conservatism.improvements"
placeholder="AFIs"
:rows="1"
:max-rows="2"
no-resize
class="afi"
></b-form-textarea>
</b-col>
</b-row>
</b-col>
</b-row>
<b-row>
<b-col cols="6" class="border">
<b-row>
<b-col cols="4">
<h5>Teamwork Communications</h5>
<score-selector
:score-value="item.teamworkCommunications.rating"
v-on:newselection="
item.teamworkCommunications.rating = $event;
updateTotals();
"
></score-selector>
</b-col>
<b-col cols="8">
<b-form-textarea
v-model="item.teamworkCommunications.strengths"
placeholder="Strengths"
:rows="1"
:max-rows="2"
no-resize
class="strength"
></b-form-textarea>
<b-form-textarea
v-model="item.teamworkCommunications.improvements"
placeholder="AFIs"
:rows="1"
:max-rows="2"
no-resize
class="afi"
></b-form-textarea>
</b-col>
</b-row>
</b-col>
<b-col cols="6" class="border">
<b-row>
<b-col cols="4">
<h5>Teamwork Leadership</h5>
<score-selector
:score-value="item.teamworkLeadership.rating"
v-on:newselection="
item.teamworkLeadership.rating = $event;
updateTotals();
"
></score-selector>
</b-col>
<b-col cols="8">
<b-form-textarea
v-model="item.teamworkLeadership.strengths"
placeholder="Strengths"
:rows="1"
:max-rows="2"
no-resize
class="strength"
></b-form-textarea>
<b-form-textarea
v-model="item.teamworkLeadership.improvements"
placeholder="AFIs"
:rows="1"
:max-rows="2"
no-resize
class="afi"
></b-form-textarea>
</b-col>
</b-row>
</b-col>
</b-row>
<b-row>
<b-col cols="6" class="border">
<b-row>
<b-col cols="4">
<h5>Teamwork Workload</h5>
<score-selector
:score-value="item.teamworkWorkload.rating"
v-on:newselection="
item.teamworkWorkload.rating = $event;
updateTotals();
"
></score-selector>
</b-col>
<b-col cols="8">
<b-form-textarea
v-model="item.teamworkWorkload.strengths"
placeholder="Strengths"
:rows="1"
:max-rows="2"
no-resize
class="strength"
></b-form-textarea>
<b-form-textarea
v-model="item.teamworkWorkload.improvements"
placeholder="AFIs"
:rows="1"
:max-rows="2"
no-resize
class="afi"
></b-form-textarea>
</b-col>
</b-row>
</b-col>
<b-col cols="6" class="border">
<b-row>
<b-col cols="4">
<h5>Knowledge</h5>
<score-selector
:score-value="item.knowledge.rating"
v-on:newselection="
item.knowledge.rating = $event;
updateTotals();
"
></score-selector>
</b-col>
<b-col cols="8">
<b-form-textarea
v-model="item.knowledge.strengths"
placeholder="Strengths"
:rows="1"
:max-rows="2"
no-resize
class="strength"
></b-form-textarea>
<b-form-textarea
v-model="item.knowledge.improvements"
placeholder="AFIs"
:rows="1"
:max-rows="2"
no-resize
class="afi"
></b-form-textarea>
</b-col>
</b-row>
</b-col>
</b-row>
</b-container> </b-container>
<b-row align-h="center">
<b-col cols="1">
<b-button type="submit" variant="primary">Submit</b-button>
</b-col>
<b-col offset="1" cols="1">
<b-button v-on:click="this.addAnotherObservation"
>Add Scenario</b-button
>
</b-col>
</b-row>
</b-form>
<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>
<p class="mt-3">
<v-icon name="exclamation-circle" scale="1.5" color="gold" />&nbsp;<i
>Leaving this page before submitting will delete all entered data.</i
>
</p>
</b-container> </b-container>
<b-container v-else>
<b-row>
<b-col>
<h2>Error</h2>
</b-col>
</b-row>
<b-row>
<b-col>
<p>
An Observation session has not been correctly setup, please try
again.
</p>
</b-col>
</b-row>
</b-container>
</b-container>
</template> </template>
<script> <script>
@ -216,7 +468,7 @@ import "vue-awesome/icons/times-circle";
import "vue-awesome/icons/exclamation-circle"; import "vue-awesome/icons/exclamation-circle";
import { mapState } from "vuex"; import { mapState } from "vuex";
import Vue from "vue"; import Vue from "vue";
import ScoreSelector from "../components/ScoreSelector.vue" import ScoreSelector from "../components/ScoreSelector.vue";
export default { export default {
name: "observation", name: "observation",
@ -421,18 +673,16 @@ export default {
tutors: this.tutors, tutors: this.tutors,
person: this.whom, person: this.whom,
type: this.type, type: this.type,
observed: this.scenarios.map(x => x.title).join(', '), observed: this.scenarios.map(x => x.title).join(", "),
scenarios: JSON.parse(JSON.stringify(this.scenarios)) scenarios: JSON.parse(JSON.stringify(this.scenarios))
}, },
axiosConfig axiosConfig
) )
.then(function(response) { //.then(function(response) {
.then(function() {
self.$router.push("/complete"); self.$router.push("/complete");
console.log(response);
})
.catch(function(error) {
console.log(error);
}); });
//.catch(function(error) {});
} }
this.clearPassword(); this.clearPassword();
form.classList.add("was-validated"); form.classList.add("was-validated");
@ -450,7 +700,7 @@ export default {
} }
.scorewarning { .scorewarning {
background-color: red; background-color: red;
} }
.top-buffer { .top-buffer {
margin-top: 10px; margin-top: 10px;
@ -506,6 +756,6 @@ img {
} }
h5 { h5 {
padding-top: 2px; padding-top: 2px;
} }
</style> </style>

View File

@ -1,11 +1,11 @@
<template> <template>
<b-container> <b-container>
<h2>Submission Complete</h2> <h2>Submission Complete</h2>
<p>{{ type }}/{{ whom }} has been submitted successfully.</p> <p>{{ type }}/{{ whom }} has been submitted successfully.</p>
<b-button size="lg" variant="primary" to="/new"> <b-button size="lg" variant="primary" to="/new">
Start New Observation Start New Observation
</b-button> </b-button>
</b-container> </b-container>
</template> </template>
<script> <script>
@ -19,5 +19,4 @@ export default {
}; };
</script> </script>
<style scoped> <style scoped></style>
</style>

View File

@ -1,73 +1,98 @@
<template> <template>
<b-container class="home" align-h="center"> <b-container class="home" align-h="center">
<b-modal ref="errorModal" class="text-center" centered hide-header hide-footer> <b-modal
<div class="modal-header"> ref="errorModal"
<h3 class="modal-title w-100">{{ errorStatus }}</h3> class="text-center"
</div> centered
<div class="d-block"> hide-header
<br/> hide-footer
<span style="font-size:20px;" v-html="errorMessage"/> >
<button class="btn btn-warning" @click="$refs.errorModal.hide()"> <div class="modal-header">
<v-icon name="exclamation-circle"/> <h3 class="modal-title w-100">{{ errorStatus }}</h3>
Dismiss </div>
</button> <div class="d-block">
</div> <br />
</b-modal> <span style="font-size:20px;" v-html="errorMessage" />
<b-container v-if="errorMessage"> <button class="btn btn-warning" @click="$refs.errorModal.hide()">
<b-alert variant="danger" show>An error occurred, refresh and try again.</b-alert> <v-icon name="exclamation-circle" />
</b-container> Dismiss
<b-container v-if="!loaded && !errorMessage"> </button>
<v-icon name="spinner" spin scale="2"/> </div>
<br/><br/> </b-modal>
<p>Loading Site Data</p> <b-container v-if="errorMessage">
</b-container> <b-alert variant="danger" show
<b-container v-if="loaded"> >An error occurred, refresh and try again.</b-alert
<b-form @submit="onSubmit" id="submission-form" novalidate> >
<b-row align-h="center">
<b-col>
<b-form-group label="Site">
<b-form-select :value="site" @input="setSite" :options="siteOptions"
style="text-align:center;" required></b-form-select>
</b-form-group>
</b-col>
</b-row>
<b-row align-h="center">
<b-col>
<b-form-group label="Participant">
<b-form-input :value="whom" @change="setWhom($event)" type="text"
style="text-align:center;" required></b-form-input>
</b-form-group>
</b-col>
</b-row>
<b-row align-h="center">
<b-col>
<b-form-group label="Type">
<b-form-select :value="type" @input="setType" style="text-align:center;"
required>
<option :value=null>Select a training type</option>
<option value="INITIAL">INITIAL</option>
<option value="CONTINUING">CONTINUING</option>
</b-form-select>
</b-form-group>
</b-col>
</b-row>
<b-row align-h="center">
<b-col>
<b-form-group label="Tutor(s)">
<p v-if="site == null">Select a site first.</p>
<v-icon name="spinner" spin v-if="loadingTutors"/>
<b-form-checkbox-group v-model="iTutors" :options="tutorOptions"></b-form-checkbox-group>
</b-form-group>
</b-col>
</b-row>
<b-row align-h="center">
<b-col>
<b-button type="submit" size="lg" variant="primary">Start</b-button>
</b-col>
</b-row>
</b-form>
</b-container>
</b-container> </b-container>
<b-container v-if="!loaded && !errorMessage">
<v-icon name="spinner" spin scale="2" />
<br /><br />
<p>Loading Site Data</p>
</b-container>
<b-container v-if="loaded">
<b-form @submit="onSubmit" id="submission-form" novalidate>
<b-row align-h="center">
<b-col>
<b-form-group label="Site">
<b-form-select
:value="site"
@input="setSite"
:options="siteOptions"
style="text-align:center;"
required
></b-form-select>
</b-form-group>
</b-col>
</b-row>
<b-row align-h="center">
<b-col>
<b-form-group label="Participant">
<b-form-input
:value="whom"
@change="setWhom($event)"
type="text"
style="text-align:center;"
required
></b-form-input>
</b-form-group>
</b-col>
</b-row>
<b-row align-h="center">
<b-col>
<b-form-group label="Type">
<b-form-select
:value="type"
@input="setType"
style="text-align:center;"
required
>
<option :value="null">Select a training type</option>
<option value="INITIAL">INITIAL</option>
<option value="CONTINUING">CONTINUING</option>
</b-form-select>
</b-form-group>
</b-col>
</b-row>
<b-row align-h="center">
<b-col>
<b-form-group label="Tutor(s)">
<p v-if="site == null">Select a site first.</p>
<v-icon name="spinner" spin v-if="loadingTutors" />
<b-form-checkbox-group
v-model="iTutors"
:options="tutorOptions"
></b-form-checkbox-group>
</b-form-group>
</b-col>
</b-row>
<b-row align-h="center">
<b-col>
<b-button type="submit" size="lg" variant="primary">Start</b-button>
</b-col>
</b-row>
</b-form>
</b-container>
</b-container>
</template> </template>
<script> <script>
@ -119,11 +144,13 @@ export default {
this.loadingTutors = true; this.loadingTutors = true;
this.tutorOptions = []; this.tutorOptions = [];
this.getTutors(); this.getTutors();
this.iTutors = this.iTutors.filter(x => this.tutorOptions.indexOf(x) !== -1) this.iTutors = this.iTutors.filter(
x => this.tutorOptions.indexOf(x) !== -1
);
}, },
iTutors: function() { iTutors: function() {
if(this.tutors !== this.iTutors) { if (this.tutors !== this.iTutors) {
this.setTutors(this.iTutors) this.setTutors(this.iTutors);
} }
} }
}, },

View File

@ -1,63 +1,116 @@
<template> <template>
<b-container fluid> <b-container fluid>
<b-modal ref="errorModal" class="text-center" centered hide-header hide-footer> <b-modal
<div class="modal-header"> ref="errorModal"
<h3 class="modal-title w-100">{{ errorStatus }}</h3> class="text-center"
</div> centered
<div class="d-block"> hide-header
<br/> hide-footer
<span style="font-size:20px;" v-html="errorMessage"/> >
<button class="btn btn-warning" @click="$refs.errorModal.hide()"> <div class="modal-header">
<v-icon name="exclamation-circle"/> <h3 class="modal-title w-100">{{ errorStatus }}</h3>
Dismiss </div>
</button> <div class="d-block">
</div> <br />
</b-modal> <span style="font-size:20px;" v-html="errorMessage" />
<b-row class="pb-2"> <button class="btn btn-warning" @click="$refs.errorModal.hide()">
<b-col> <v-icon name="exclamation-circle" />
<b-button-group size="sm"> Dismiss
<b-button variant="dark">Select Chart:</b-button> </button>
<b-button variant="outline-primary" @click="chartMode = 0; getFilteredAverage()">Trends</b-button> </div>
<b-button variant="outline-primary" @click="chartMode = 1; getFilteredAverage()">AFIs</b-button> </b-modal>
</b-button-group> <b-row class="pb-2">
</b-col> <b-col>
<b-col> <b-button-group size="sm">
<b-button-group size="sm"> <b-button variant="dark">Select Chart:</b-button>
<b-button variant="dark">Quick Interval:</b-button> <b-button
<b-button variant="outline-primary" v-on:click="setInterval(1, 'w'); getFilteredAverage()">1 Week</b-button> variant="outline-primary"
<b-button variant="outline-primary" v-on:click="setInterval(1, 'M'); getFilteredAverage()">1 Month</b-button> @click="
<b-button variant="outline-primary" v-on:click="setInterval(3, 'M'); getFilteredAverage()">3 Months</b-button> chartMode = 0;
<b-button variant="outline-primary" v-on:click="setInterval(1, 'y'); getFilteredAverage()">1 Year</b-button> getFilteredAverage();
</b-button-group> "
</b-col> >Trends</b-button
</b-row> >
<observation-search-bar v-on:refresh="getFilteredAverage()"></observation-search-bar> <b-button
<b-row v-if="chartData != null && chartData.labels.length > 0 && !loading"> variant="outline-primary"
<b-col v-if="chartMode == 0"> @click="
<stats-view v-bind:chartData="chartData" chartMode = 1;
style="position: relative; height:80vh" :options="options"/> getFilteredAverage();
</b-col> "
<b-col v-else-if="chartMode == 1"> >AFIs</b-button
<afi-pie :chartData="chartData" :options="pieOptions"/> >
</b-col> </b-button-group>
</b-row> </b-col>
<b-row v-else-if="loading"> <b-col>
Loading... <b-button-group size="sm">
</b-row> <b-button variant="dark">Quick Interval:</b-button>
<b-row v-else> <b-button
<b-col> variant="outline-primary"
<v-icon name="search"></v-icon> v-on:click="
<p>No data found with the given search parameters.</p> setInterval(1, 'w');
</b-col> getFilteredAverage();
</b-row> "
</b-container> >1 Week</b-button
>
<b-button
variant="outline-primary"
v-on:click="
setInterval(1, 'M');
getFilteredAverage();
"
>1 Month</b-button
>
<b-button
variant="outline-primary"
v-on:click="
setInterval(3, 'M');
getFilteredAverage();
"
>3 Months</b-button
>
<b-button
variant="outline-primary"
v-on:click="
setInterval(1, 'y');
getFilteredAverage();
"
>1 Year</b-button
>
</b-button-group>
</b-col>
</b-row>
<observation-search-bar
v-on:refresh="getFilteredAverage()"
></observation-search-bar>
<b-row v-if="chartData != null && chartData.labels.length > 0 && !loading">
<b-col v-if="chartMode == 0">
<stats-view
v-bind:chartData="chartData"
style="position: relative; height:80vh"
:options="options"
/>
</b-col>
<b-col v-else-if="chartMode == 1">
<afi-pie :chartData="chartData" :options="pieOptions" />
</b-col>
</b-row>
<b-row v-else-if="loading">
Loading...
</b-row>
<b-row v-else>
<b-col>
<v-icon name="search"></v-icon>
<p>No data found with the given search parameters.</p>
</b-col>
</b-row>
</b-container>
</template> </template>
<script> <script>
import Vue from "vue"; import Vue from "vue";
import StatsView from "../components/StatsView"; import StatsView from "../components/StatsView";
import AfiPie from "../components/AfiPie" import AfiPie from "../components/AfiPie";
import ObservationSearchBar from "../components/ObservationSearchBar" import ObservationSearchBar from "../components/ObservationSearchBar";
import "vue-awesome/icons/exclamation-circle"; import "vue-awesome/icons/exclamation-circle";
import "vue-awesome/icons/search"; import "vue-awesome/icons/search";
@ -106,7 +159,7 @@ export default {
] ]
} }
}, },
pieOptions:{ pieOptions: {
maintainAspectRatio: false maintainAspectRatio: false
}, },
errorStatus: null, errorStatus: null,
@ -115,19 +168,19 @@ export default {
}, },
computed: { computed: {
startDate: { startDate: {
get(){ get() {
return this.$store.state.search.start; return this.$store.state.search.start;
}, },
set(data){ set(data) {
this.$store.commit('setSearchStartDate', data); this.$store.commit("setSearchStartDate", data);
} }
}, },
endDate: { endDate: {
get(){ get() {
return this.$store.state.search.end; return this.$store.state.search.end;
}, },
set(data){ set(data) {
this.$store.commit('setSearchEndDate', data); this.$store.commit("setSearchEndDate", data);
} }
} }
}, },
@ -154,7 +207,7 @@ export default {
this.loading = false; this.loading = false;
}); });
}, },
setInterval: function(amount, timeType){ setInterval: function(amount, timeType) {
this.endDate = moment(); this.endDate = moment();
this.startDate = moment().subtract(amount, timeType); this.startDate = moment().subtract(amount, timeType);
} }

View File

@ -1,14 +1,20 @@
<template> <template>
<b-container fluid> <b-container fluid>
<b-modal ref="errorModal" class="text-center" centered hide-header hide-footer> <b-modal
ref="errorModal"
class="text-center"
centered
hide-header
hide-footer
>
<div class="modal-header"> <div class="modal-header">
<h3 class="modal-title w-100">{{ errorStatus }}</h3> <h3 class="modal-title w-100">{{ errorStatus }}</h3>
</div> </div>
<div class="d-block"> <div class="d-block">
<br> <br />
<span style="font-size:20px;" v-html="errorMessage"/> <span style="font-size:20px;" v-html="errorMessage" />
<button class="btn btn-warning" @click="$refs.errorModal.hide()"> <button class="btn btn-warning" @click="$refs.errorModal.hide()">
<v-icon name="exclamation-circle"/>Dismiss <v-icon name="exclamation-circle" />Dismiss
</button> </button>
</div> </div>
</b-modal> </b-modal>
@ -18,47 +24,76 @@
<b-button variant="dark">Quick Interval:</b-button> <b-button variant="dark">Quick Interval:</b-button>
<b-button <b-button
variant="outline-primary" variant="outline-primary"
v-on:click="setInterval(1, 'w'); getFiltered()" v-on:click="
>1 Week</b-button> setInterval(1, 'w');
getFiltered();
"
>1 Week</b-button
>
<b-button <b-button
variant="outline-primary" variant="outline-primary"
v-on:click="setInterval(1, 'M'); getFiltered()" v-on:click="
>1 Month</b-button> setInterval(1, 'M');
getFiltered();
"
>1 Month</b-button
>
<b-button <b-button
variant="outline-primary" variant="outline-primary"
v-on:click="setInterval(3, 'M'); getFiltered()" v-on:click="
>3 Months</b-button> setInterval(3, 'M');
getFiltered();
"
>3 Months</b-button
>
<b-button <b-button
variant="outline-primary" variant="outline-primary"
v-on:click="setInterval(1, 'y'); getFiltered()" v-on:click="
>1 Year</b-button> setInterval(1, 'y');
getFiltered();
"
>1 Year</b-button
>
</b-button-group> </b-button-group>
</b-col> </b-col>
</b-row> </b-row>
<observation-search-bar v-on:refresh="getFiltered()"></observation-search-bar> <observation-search-bar
<b-container v-if="observationData != null && observationData.length > 0" fluid> v-on:refresh="getFiltered()"
></observation-search-bar>
<b-container
v-if="observationData != null && observationData.length > 0"
fluid
>
<b-card no-body> <b-card no-body>
<b-tabs pills card vertical> <b-tabs pills card vertical>
<b-tab v-for="(observation, index) in observationData" v-bind:key="index"> <b-tab
v-for="(observation, index) in observationData"
v-bind:key="index"
>
<p slot="title"> <p slot="title">
{{ observation.date }} {{ observation.date }}
<br> <br />
{{ observation.whom }} {{ observation.type }} {{ observation.whom }} {{ observation.type }}
<br> <br />
{{ shortenedString(observation.observed) }} {{ shortenedString(observation.observed) }}
</p> </p>
<h2> <h2>
{{ observation.date }}, {{ observation.whom }} {{ observation.date }}, {{ observation.whom }}
<br> <br />
{{ observation.type }} / {{ observation.observed }} {{ observation.type }} / {{ observation.observed }}
</h2> </h2>
<b-row align-h="center"> <b-row align-h="center">
<h4> <h4>
Observed by: Observed by:
<span v-bind:key="index" v-for="(tutor, index) in observation.tutors"> <span
v-bind:key="index"
v-for="(tutor, index) in observation.tutors"
>
<i> <i>
{{ tutor.name }} {{ tutor.name }}
<span v-if="index+1 < observation.tutors.length">,&nbsp;</span> <span v-if="index + 1 < observation.tutors.length"
>,&nbsp;</span
>
</i> </i>
</span> </span>
</h4> </h4>
@ -66,74 +101,112 @@
<b-row align-h="center"> <b-row align-h="center">
<h4>Participant:&nbsp;{{ observation.person.name }}</h4> <h4>Participant:&nbsp;{{ observation.person.name }}</h4>
</b-row> </b-row>
<br> <br />
<b-row class="mb-2"> <b-row class="mb-2">
<b-col class="centered-image" v-if="observation.monitoring"> <b-col class="centered-image" v-if="observation.monitoring">
<img <img
src="../assets/Monitoring.svg" src="../assets/Monitoring.svg"
class="image-opacity" class="image-opacity"
v-bind:class="{ scorewarning: observation.monitoring < 2.5 }" v-bind:class="{ scorewarning: observation.monitoring < 2.5 }"
> />
<div class="image-centered-text">{{ observation.monitoring.toFixed(1) }}</div> <div class="image-centered-text">
{{ observation.monitoring.toFixed(1) }}
</div>
</b-col> </b-col>
<b-col class="centered-image" v-if="observation.controlProcedural"> <b-col
class="centered-image"
v-if="observation.controlProcedural"
>
<img <img
src="../assets/Control.svg" src="../assets/Control.svg"
class="image-opacity" class="image-opacity"
v-bind:class="{ scorewarning: observation.controlProcedural < 2.5 }" v-bind:class="{
> scorewarning: observation.controlProcedural < 2.5
<div class="image-centered-text">{{ observation.controlProcedural.toFixed(1) }}</div> }"
/>
<div class="image-centered-text">
{{ observation.controlProcedural.toFixed(1) }}
</div>
</b-col> </b-col>
<b-col class="centered-image" v-if="observation.control"> <b-col class="centered-image" v-if="observation.control">
<img <img
src="../assets/Control.svg" src="../assets/Control.svg"
class="image-opacity" class="image-opacity"
v-bind:class="{ scorewarning: observation.control < 2.5 }" v-bind:class="{ scorewarning: observation.control < 2.5 }"
> />
<div class="image-centered-text">{{ observation.control.toFixed(1) }}</div> <div class="image-centered-text">
{{ observation.control.toFixed(1) }}
</div>
</b-col> </b-col>
<b-col class="centered-image" v-if="observation.conservatism"> <b-col class="centered-image" v-if="observation.conservatism">
<img <img
src="../assets/Conservatism.svg" src="../assets/Conservatism.svg"
class="image-opacity" class="image-opacity"
v-bind:class="{ scorewarning: observation.conservatism < 2.5 }" v-bind:class="{
> scorewarning: observation.conservatism < 2.5
<div class="image-centered-text">{{ observation.conservatism.toFixed(1) }}</div> }"
/>
<div class="image-centered-text">
{{ observation.conservatism.toFixed(1) }}
</div>
</b-col> </b-col>
<b-col class="centered-image" v-if="observation.teamworkCommunications"> <b-col
class="centered-image"
v-if="observation.teamworkCommunications"
>
<img <img
src="../assets/Teamwork.svg" src="../assets/Teamwork.svg"
class="image-opacity" class="image-opacity"
v-bind:class="{ scorewarning: observation.teamworkCommunications < 2.5 }" v-bind:class="{
> scorewarning: observation.teamworkCommunications < 2.5
<div class="image-centered-text">{{ observation.teamworkCommunications.toFixed(1) }}</div> }"
/>
<div class="image-centered-text">
{{ observation.teamworkCommunications.toFixed(1) }}
</div>
</b-col> </b-col>
<b-col class="centered-image" v-if="observation.teamworkLeadership"> <b-col
class="centered-image"
v-if="observation.teamworkLeadership"
>
<img <img
src="../assets/Teamwork.svg" src="../assets/Teamwork.svg"
class="image-opacity" class="image-opacity"
v-bind:class="{ scorewarning: observation.teamworkLeadership < 2.5 }" v-bind:class="{
> scorewarning: observation.teamworkLeadership < 2.5
<div class="image-centered-text">{{ observation.teamworkLeadership.toFixed(1) }}</div> }"
/>
<div class="image-centered-text">
{{ observation.teamworkLeadership.toFixed(1) }}
</div>
</b-col> </b-col>
<b-col class="centered-image" v-if="observation.teamworkWorkload"> <b-col class="centered-image" v-if="observation.teamworkWorkload">
<img <img
src="../assets/Teamwork.svg" src="../assets/Teamwork.svg"
class="image-opacity" class="image-opacity"
v-bind:class="{ scorewarning: observation.teamworkWorkload < 2.5 }" v-bind:class="{
> scorewarning: observation.teamworkWorkload < 2.5
<div class="image-centered-text">{{ observation.teamworkWorkload.toFixed(1) }}</div> }"
/>
<div class="image-centered-text">
{{ observation.teamworkWorkload.toFixed(1) }}
</div>
</b-col> </b-col>
<b-col class="centered-image" v-if="observation.knowledge"> <b-col class="centered-image" v-if="observation.knowledge">
<img <img
src="../assets/Knowledge.svg" src="../assets/Knowledge.svg"
class="image-opacity" class="image-opacity"
v-bind:class="{ scorewarning: observation.knowledge < 2.5 }" v-bind:class="{ scorewarning: observation.knowledge < 2.5 }"
> />
<div class="image-centered-text">{{ observation.knowledge.toFixed(1) }}</div> <div class="image-centered-text">
{{ observation.knowledge.toFixed(1) }}
</div>
</b-col> </b-col>
</b-row> </b-row>
<b-row v-for="(entry, index2) in observation.scenarios" v-bind:key="index2"> <b-row
v-for="(entry, index2) in observation.scenarios"
v-bind:key="index2"
>
<b-col class="border"> <b-col class="border">
<b-row align-h="center"> <b-row align-h="center">
<h3>{{ entry.title }}</h3> <h3>{{ entry.title }}</h3>
@ -149,7 +222,10 @@
></observation-entry> ></observation-entry>
</b-row> </b-row>
<b-row> <b-row>
<observation-entry :scenariofundamental="entry.control" :description="'Control'"></observation-entry> <observation-entry
:scenariofundamental="entry.control"
:description="'Control'"
></observation-entry>
<observation-entry <observation-entry
:scenariofundamental="entry.conservatism" :scenariofundamental="entry.conservatism"
:description="'Conservatism'" :description="'Conservatism'"
@ -182,7 +258,7 @@
</b-card> </b-card>
<b-button class="mt-2" variant="success" @click="getCSV()" <b-button class="mt-2" variant="success" @click="getCSV()"
>CSV Dump</b-button >CSV Dump</b-button
> >&nbsp;
<b-button class="mt-2" variant="success" @click="sendEmail()" <b-button class="mt-2" variant="success" @click="sendEmail()"
>Send as Email</b-button >Send as Email</b-button
> >