diff --git a/@xen-orchestra/web/src/components/site/dashboard/PoolsStatus.vue b/@xen-orchestra/web/src/components/site/dashboard/PoolsStatus.vue
new file mode 100644
index 00000000000..836be760cfa
--- /dev/null
+++ b/@xen-orchestra/web/src/components/site/dashboard/PoolsStatus.vue
@@ -0,0 +1,59 @@
+
+
+ {{ $t('pools-status') }}
+
+
+
+
+
+
+
+
+
+
diff --git a/@xen-orchestra/web/src/locales/en.json b/@xen-orchestra/web/src/locales/en.json
index 2b8ecc0a5ed..0d8fbccf255 100644
--- a/@xen-orchestra/web/src/locales/en.json
+++ b/@xen-orchestra/web/src/locales/en.json
@@ -13,6 +13,13 @@
"n-hosts": "1 host | {n} hosts",
"no-results": "No results",
+ "pools-status": "Servers status",
+ "pools-status.connected": "Connected",
+ "pools-status.unreachable": "Unreachable",
+ "pools-status.unreachable.tooltip": "Configured servers that can not be reached",
+ "pools-status.unknown": "Unknown",
+ "pools-status.unknown.tooltip": "Servers currently connecting or in an unknown state",
+
"sidebar.search-tree-view": "Search in treeview",
"sidebar.vms-treeview": "VMs treeview",
diff --git a/@xen-orchestra/web/src/locales/fr.json b/@xen-orchestra/web/src/locales/fr.json
index cb7e0826eb3..7bae176471f 100644
--- a/@xen-orchestra/web/src/locales/fr.json
+++ b/@xen-orchestra/web/src/locales/fr.json
@@ -13,6 +13,13 @@
"n-hosts": "1 hôte | {n} hôtes",
"no-results": "Aucun résultat",
+ "pools-status": "Statut des pools",
+ "pools-status.connected": "Connectés",
+ "pools-status.unreachable": "Injoignables",
+ "pools-status.unreachable.tooltip": "Serveurs configurés mais non joignables",
+ "pools-status.unknown": "Inconnu",
+ "pools-status.unknown.tooltip": "Serveurs en cours de connexion ou dans un état inconnu",
+
"sidebar.search-tree-view": "Rechercher dans l'arborescence",
"sidebar.vms-treeview": "Arborescence des VMs",
diff --git a/@xen-orchestra/web/src/pages/index.vue b/@xen-orchestra/web/src/pages/index.vue
index 8e27fcac872..8b417b29b6b 100644
--- a/@xen-orchestra/web/src/pages/index.vue
+++ b/@xen-orchestra/web/src/pages/index.vue
@@ -1,5 +1,6 @@
@@ -7,6 +8,7 @@
@@ -23,6 +25,10 @@ import VmsStatus from '@/components/site/dashboard/VmsStatus.vue'
'alarms alarms alarms alarms alarms alarms alarms patches';
}
+.pools-status {
+ grid-area: pools-status;
+}
+
.hosts-status {
grid-area: hosts-status;
}
diff --git a/@xen-orchestra/web/src/stores/xo-rest-api/server.store.ts b/@xen-orchestra/web/src/stores/xo-rest-api/server.store.ts
new file mode 100644
index 00000000000..73b57dc826e
--- /dev/null
+++ b/@xen-orchestra/web/src/stores/xo-rest-api/server.store.ts
@@ -0,0 +1,23 @@
+import { SERVER_STATUS } from '@/types/server.type'
+import { createXoStoreConfig } from '@/utils/create-xo-store-config.util'
+import { createSubscribableStoreContext } from '@core/utils/create-subscribable-store-context.util'
+import { defineStore } from 'pinia'
+import { computed } from 'vue'
+
+export const useServerStore = defineStore('server', () => {
+ const { context: baseContext, ...configRest } = createXoStoreConfig('server')
+
+ const records = computed(() =>
+ // Filter out disconnected servers when there is a connected server in the same pool
+ baseContext.records.value.filter(
+ server => server.status !== SERVER_STATUS.DISCONNECTED || !server.error?.connectedServerId
+ )
+ )
+
+ const context = {
+ ...baseContext,
+ records,
+ }
+
+ return createSubscribableStoreContext({ context, ...configRest }, {})
+})
diff --git a/@xen-orchestra/web/src/types/server.type.ts b/@xen-orchestra/web/src/types/server.type.ts
new file mode 100644
index 00000000000..b6bd22df0b1
--- /dev/null
+++ b/@xen-orchestra/web/src/types/server.type.ts
@@ -0,0 +1,34 @@
+import type { RecordId } from '@/types/xo-object.type'
+
+export enum SERVER_STATUS {
+ CONNECTED = 'connected',
+ CONNECTING = 'connecting',
+ DISCONNECTED = 'disconnected',
+}
+
+type BaseServer = {
+ allowUnauthorized: boolean
+ enabled: boolean
+ host: string
+ id: RecordId<'server'>
+ label: string | undefined
+ readOnly: boolean
+ type: 'server'
+ username: string
+}
+
+type ConnectedServer = BaseServer & {
+ status: SERVER_STATUS.CONNECTED
+ poolId: RecordId<'pool'>
+}
+
+type ConnectingServer = BaseServer & {
+ status: SERVER_STATUS.CONNECTING
+}
+
+type DisconnectedServer = BaseServer & {
+ status: SERVER_STATUS.DISCONNECTED
+ error?: any
+}
+
+export type Server = ConnectedServer | ConnectingServer | DisconnectedServer
diff --git a/@xen-orchestra/web/src/types/xo-object.type.ts b/@xen-orchestra/web/src/types/xo-object.type.ts
index c14271d6e8d..95622ecc164 100644
--- a/@xen-orchestra/web/src/types/xo-object.type.ts
+++ b/@xen-orchestra/web/src/types/xo-object.type.ts
@@ -1,5 +1,6 @@
import type { Host } from '@/types/host.type'
import type { Pool } from '@/types/pool.type'
+import type { Server } from '@/types/server.type'
import type { Task } from '@/types/task.type'
import type { Vm } from '@/types/vm.type'
import type { ComputedRef, Ref } from 'vue'
@@ -9,7 +10,7 @@ declare const __brand: unique symbol
// eslint-disable-next-line no-use-before-define
export type RecordId = string & { [__brand]: `${Type}Id` }
-export type XoObject = Vm | Host | Pool | Task
+export type XoObject = Vm | Host | Pool | Task | Server
export type XoObjectType = XoObject['type']
diff --git a/@xen-orchestra/web/src/utils/rest-api-config.util.ts b/@xen-orchestra/web/src/utils/rest-api-config.util.ts
index bad134cda23..02793028fea 100644
--- a/@xen-orchestra/web/src/utils/rest-api-config.util.ts
+++ b/@xen-orchestra/web/src/utils/rest-api-config.util.ts
@@ -17,4 +17,8 @@ export const restApiConfig: Record