Webapp: show farm status in header bar
Show the farm status in the webapp header bar, and respond to farm status events to update it when necessary.
This commit is contained in:
parent
c1a9b1e877
commit
59bf389018
@ -17,6 +17,7 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
<farm-status :status="farmStatus.status()" />
|
||||||
<api-spinner />
|
<api-spinner />
|
||||||
<span class="app-version">
|
<span class="app-version">
|
||||||
<a :href="backendURL('/flamenco-addon.zip')">add-on</a>
|
<a :href="backendURL('/flamenco-addon.zip')">add-on</a>
|
||||||
@ -31,8 +32,10 @@ import * as API from '@/manager-api';
|
|||||||
import { getAPIClient } from '@/api-client';
|
import { getAPIClient } from '@/api-client';
|
||||||
import { backendURL } from '@/urls';
|
import { backendURL } from '@/urls';
|
||||||
import { useSocketStatus } from '@/stores/socket-status';
|
import { useSocketStatus } from '@/stores/socket-status';
|
||||||
|
import { useFarmStatus } from '@/stores/farmstatus';
|
||||||
|
|
||||||
import ApiSpinner from '@/components/ApiSpinner.vue';
|
import ApiSpinner from '@/components/ApiSpinner.vue';
|
||||||
|
import FarmStatus from '@/components/FarmStatus.vue';
|
||||||
|
|
||||||
const DEFAULT_FLAMENCO_NAME = 'Flamenco';
|
const DEFAULT_FLAMENCO_NAME = 'Flamenco';
|
||||||
const DEFAULT_FLAMENCO_VERSION = 'unknown';
|
const DEFAULT_FLAMENCO_VERSION = 'unknown';
|
||||||
@ -41,15 +44,18 @@ export default {
|
|||||||
name: 'App',
|
name: 'App',
|
||||||
components: {
|
components: {
|
||||||
ApiSpinner,
|
ApiSpinner,
|
||||||
|
FarmStatus,
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
flamencoName: DEFAULT_FLAMENCO_NAME,
|
flamencoName: DEFAULT_FLAMENCO_NAME,
|
||||||
flamencoVersion: DEFAULT_FLAMENCO_VERSION,
|
flamencoVersion: DEFAULT_FLAMENCO_VERSION,
|
||||||
backendURL: backendURL,
|
backendURL: backendURL,
|
||||||
|
farmStatus: useFarmStatus(),
|
||||||
}),
|
}),
|
||||||
mounted() {
|
mounted() {
|
||||||
window.app = this;
|
window.app = this;
|
||||||
this.fetchManagerInfo();
|
this.fetchManagerInfo();
|
||||||
|
this.fetchFarmStatus();
|
||||||
|
|
||||||
const sockStatus = useSocketStatus();
|
const sockStatus = useSocketStatus();
|
||||||
this.$watch(
|
this.$watch(
|
||||||
@ -71,6 +77,14 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
fetchFarmStatus() {
|
||||||
|
const metaAPI = new API.MetaApi(getAPIClient());
|
||||||
|
metaAPI.getFarmStatus().then((statusReport) => {
|
||||||
|
const apiStatusReport = API.FarmStatusReport.constructFromObject(statusReport);
|
||||||
|
this.farmStatus.lastStatusReport = apiStatusReport;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
socketIOReconnect() {
|
socketIOReconnect() {
|
||||||
const metaAPI = new API.MetaApi(getAPIClient());
|
const metaAPI = new API.MetaApi(getAPIClient());
|
||||||
metaAPI.getVersion().then((version) => {
|
metaAPI.getVersion().then((version) => {
|
||||||
|
@ -82,6 +82,14 @@
|
|||||||
--color-worker-status-testing: hsl(166 100% 46%);
|
--color-worker-status-testing: hsl(166 100% 46%);
|
||||||
--color-worker-status-offline: var(--color-status-canceled);
|
--color-worker-status-offline: var(--color-status-canceled);
|
||||||
|
|
||||||
|
--color-farm-status-starting: hsl(68, 100%, 30%);
|
||||||
|
--color-farm-status-active: var(--color-status-active);
|
||||||
|
--color-farm-status-idle: var(--color-status-paused);
|
||||||
|
--color-farm-status-waiting: var(--color-status-soft-failed);
|
||||||
|
--color-farm-status-asleep: var(--color-worker-status-asleep);
|
||||||
|
--color-farm-status-inoperative: var(--color-status-failed);
|
||||||
|
--color-farm-status-unknown: var(--color-status-failed);
|
||||||
|
|
||||||
--color-connection-lost-text: hsl(0, 90%, 60%);
|
--color-connection-lost-text: hsl(0, 90%, 60%);
|
||||||
--color-connection-lost-bg: hsl(0, 50%, 20%);
|
--color-connection-lost-bg: hsl(0, 50%, 20%);
|
||||||
}
|
}
|
||||||
|
35
web/app/src/components/FarmStatus.vue
Normal file
35
web/app/src/components/FarmStatus.vue
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<template>
|
||||||
|
<span id="farmstatus" v-if="status"
|
||||||
|
>Farm status: <span :class="'farm-status-' + status">{{ status }}</span></span
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const props = defineProps(['status']);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
span#farmstatus {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.farm-status-starting {
|
||||||
|
color: var(--color-farm-status-starting);
|
||||||
|
}
|
||||||
|
.farm-status-active {
|
||||||
|
color: var(--color-farm-status-active);
|
||||||
|
}
|
||||||
|
.farm-status-idle {
|
||||||
|
color: var(--color-farm-status-idle);
|
||||||
|
}
|
||||||
|
.farm-status-waiting {
|
||||||
|
color: var(--color-farm-status-waiting);
|
||||||
|
}
|
||||||
|
.farm-status-asleep {
|
||||||
|
color: var(--color-farm-status-asleep);
|
||||||
|
}
|
||||||
|
.farm-status-inoperative,
|
||||||
|
.farm-status-unknown {
|
||||||
|
color: var(--color-farm-status-inoperative);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
@ -7,6 +7,7 @@ import io from 'socket.io-client';
|
|||||||
import { ws } from '@/urls';
|
import { ws } from '@/urls';
|
||||||
import * as API from '@/manager-api';
|
import * as API from '@/manager-api';
|
||||||
import { useSocketStatus } from '@/stores/socket-status';
|
import { useSocketStatus } from '@/stores/socket-status';
|
||||||
|
import { useFarmStatus } from '@/stores/farmstatus';
|
||||||
|
|
||||||
const websocketURL = ws();
|
const websocketURL = ws();
|
||||||
|
|
||||||
@ -34,6 +35,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
socket: null,
|
socket: null,
|
||||||
sockStatus: useSocketStatus(),
|
sockStatus: useSocketStatus(),
|
||||||
|
farmStatus: useFarmStatus(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
@ -182,6 +184,13 @@ export default {
|
|||||||
this.$emit('workerTagUpdate', apiWorkerTagUpdate);
|
this.$emit('workerTagUpdate', apiWorkerTagUpdate);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.socket.on('/status', (farmStatusReport) => {
|
||||||
|
// Convert to API object, in order to have the same parsing of data as
|
||||||
|
// when we'd do an API call.
|
||||||
|
const apiFarmStatusReport = API.FarmStatusReport.constructFromObject(farmStatusReport);
|
||||||
|
this.farmStatus.lastStatusReport = apiFarmStatusReport;
|
||||||
|
});
|
||||||
|
|
||||||
// Chat system, useful for debugging.
|
// Chat system, useful for debugging.
|
||||||
this.socket.on('/message', (message) => {
|
this.socket.on('/message', (message) => {
|
||||||
this.$emit('message', message);
|
this.$emit('message', message);
|
||||||
|
17
web/app/src/stores/farmstatus.js
Normal file
17
web/app/src/stores/farmstatus.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { FarmStatusReport } from '@/manager-api';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keep track of the farm status. This is updated from UpdateListener.vue.
|
||||||
|
*/
|
||||||
|
export const useFarmStatus = defineStore('farmStatus', {
|
||||||
|
state: () => ({
|
||||||
|
lastStatusReport: new FarmStatusReport(),
|
||||||
|
}),
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
status() {
|
||||||
|
return this.lastStatusReport.status;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user