diff options
Diffstat (limited to 'master/client/src/components/MinionStatus.vue')
-rw-r--r-- | master/client/src/components/MinionStatus.vue | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/master/client/src/components/MinionStatus.vue b/master/client/src/components/MinionStatus.vue new file mode 100644 index 0000000..ec2564c --- /dev/null +++ b/master/client/src/components/MinionStatus.vue @@ -0,0 +1,110 @@ +<template> + <div class="minion"> + <span class="name">{{ name }}</span> + <span class="ip">{{ ip }}</span> + Temperature: {{ temperature }} + </div> +</template> + +<script lang="ts"> +import { ref, defineComponent } from "vue"; + +interface MinionResponseData { + data: { temperature: number } | null, + error: string | null +} + +export default defineComponent( + { + name: "MinionStatus", + props: { + name: { + type: String, + required: true + }, + ip: { + type: String, + required: true + } + }, + setup(props) { + const temperature = ref("None"); + + async function fetch_temperature() { + let response: Response; + + try { + response = await fetch(`http://${props.ip}`); + } + catch (err) { + const error = err as Error; + + console.error( + `Failed to fetch temperature for minion "${props.name}". ` + + `${error.message}` + ); + return; + } + + const data = await response.json() as MinionResponseData; + + if(!response.ok) { + if(data.error !== null) { + console.error( + `Minion "${props.name}" responded with status ` + + `${response.status} and error "${data.error}"` + ); + } + else { + console.error( + `Minion "${props.name}" responded with status ` + + `${response.status} and a unknown error` + ); + } + + return; + } + + if(data.data == null) { + console.error(`Minion "${props.name}" has no data in response`); + return; + } + + temperature.value = `${data.data.temperature}°C`; + } + + return { temperature, fetch_temperature }; + }, + created() { + this.fetch_temperature(); + } + } +); +</script> + +<style scoped lang="scss"> +@use "@/scss/colors"; + +.minion { + background-color: lighten(colors.$background, 8%); + width: fit-content; + padding-top: 1em; + padding-bottom: 1.5em; + padding-left: 1.5em; + padding-right: 3em; + border: 1px solid lighten(colors.$background, 14%); + border-radius: 8px; + + .name { + display: block; + font-size: 1.25rem; + font-weight: 700; + color: colors.$primary; + margin-bottom: 0.25em; + } + + .ip { + display: block; + } +} +</style> |