diff --git a/web/app/src/App.vue b/web/app/src/App.vue index 3e9327ce..4cd53a4e 100644 --- a/web/app/src/App.vue +++ b/web/app/src/App.vue @@ -17,6 +17,7 @@ + add-on @@ -31,8 +32,10 @@ import * as API from '@/manager-api'; import { getAPIClient } from '@/api-client'; import { backendURL } from '@/urls'; import { useSocketStatus } from '@/stores/socket-status'; +import { useFarmStatus } from '@/stores/farmstatus'; import ApiSpinner from '@/components/ApiSpinner.vue'; +import FarmStatus from '@/components/FarmStatus.vue'; const DEFAULT_FLAMENCO_NAME = 'Flamenco'; const DEFAULT_FLAMENCO_VERSION = 'unknown'; @@ -41,15 +44,18 @@ export default { name: 'App', components: { ApiSpinner, + FarmStatus, }, data: () => ({ flamencoName: DEFAULT_FLAMENCO_NAME, flamencoVersion: DEFAULT_FLAMENCO_VERSION, backendURL: backendURL, + farmStatus: useFarmStatus(), }), mounted() { window.app = this; this.fetchManagerInfo(); + this.fetchFarmStatus(); const sockStatus = useSocketStatus(); 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() { const metaAPI = new API.MetaApi(getAPIClient()); metaAPI.getVersion().then((version) => { diff --git a/web/app/src/assets/base.css b/web/app/src/assets/base.css index 9e3f1e3e..eddcb115 100644 --- a/web/app/src/assets/base.css +++ b/web/app/src/assets/base.css @@ -82,6 +82,14 @@ --color-worker-status-testing: hsl(166 100% 46%); --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-bg: hsl(0, 50%, 20%); } diff --git a/web/app/src/components/FarmStatus.vue b/web/app/src/components/FarmStatus.vue new file mode 100644 index 00000000..16411dcf --- /dev/null +++ b/web/app/src/components/FarmStatus.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/web/app/src/components/UpdateListener.vue b/web/app/src/components/UpdateListener.vue index 6e385949..b9b966e7 100644 --- a/web/app/src/components/UpdateListener.vue +++ b/web/app/src/components/UpdateListener.vue @@ -7,6 +7,7 @@ import io from 'socket.io-client'; import { ws } from '@/urls'; import * as API from '@/manager-api'; import { useSocketStatus } from '@/stores/socket-status'; +import { useFarmStatus } from '@/stores/farmstatus'; const websocketURL = ws(); @@ -34,6 +35,7 @@ export default { return { socket: null, sockStatus: useSocketStatus(), + farmStatus: useFarmStatus(), }; }, mounted: function () { @@ -182,6 +184,13 @@ export default { 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. this.socket.on('/message', (message) => { this.$emit('message', message); diff --git a/web/app/src/stores/farmstatus.js b/web/app/src/stores/farmstatus.js new file mode 100644 index 00000000..678b513a --- /dev/null +++ b/web/app/src/stores/farmstatus.js @@ -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; + }, + }, +});