mirror of
https://github.com/vatesfr/xen-orchestra.git
synced 2026-11-09 17:06:13 -06:00
Compare commits
17 Commits
326c152fac
...
pool-statu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e55e43157a | ||
|
|
c6f7f53d1d | ||
|
|
1fd3bb86ec | ||
|
|
c66ccf36e1 | ||
|
|
fbfd170d0e | ||
|
|
55e4919902 | ||
|
|
a993b5dec5 | ||
|
|
050f31a3d6 | ||
|
|
9d27020135 | ||
|
|
69c082a917 | ||
|
|
0427e09738 | ||
|
|
2515311c6e | ||
|
|
6d623666ca | ||
|
|
18bdc3971c | ||
|
|
cf11ffcc11 | ||
|
|
8834b25926 | ||
|
|
b053eef0a5 |
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<UiCard>
|
||||
<UiCardTitle>{{ $t('pools-status') }}</UiCardTitle>
|
||||
<VtsLoadingHero :disabled="isReady" type="card">
|
||||
<VtsDonutChartWithLegend :icon="faCity" :segments />
|
||||
<UiCardNumbers :value="servers.length" class="total" label="Total" size="small" />
|
||||
</VtsLoadingHero>
|
||||
</UiCard>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { usePoolStore } from '@/stores/xo-rest-api/pool.store'
|
||||
import { useServerStore } from '@/stores/xo-rest-api/server.store'
|
||||
import { SERVER_STATUS } from '@/types/xo/server.type'
|
||||
import VtsDonutChartWithLegend, {
|
||||
type DonutChartWithLegendProps,
|
||||
} from '@core/components/donut-chart-with-legend/VtsDonutChartWithLegend.vue'
|
||||
import VtsLoadingHero from '@core/components/state-hero/VtsLoadingHero.vue'
|
||||
import UiCard from '@core/components/ui/card/UiCard.vue'
|
||||
import UiCardNumbers from '@core/components/ui/card-numbers/UiCardNumbers.vue'
|
||||
import UiCardTitle from '@core/components/ui/card-title/UiCardTitle.vue'
|
||||
import { useItemCounter } from '@core/composables/item-counter.composable'
|
||||
import { faCity } from '@fortawesome/free-solid-svg-icons'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
const { records: servers, isReady } = useServerStore().subscribe()
|
||||
const { has: hasPool } = usePoolStore().subscribe()
|
||||
|
||||
const serversCount = useItemCounter(servers, {
|
||||
connected: server => server.status === SERVER_STATUS.CONNECTED && hasPool(server.poolId),
|
||||
unreachable: ({ status }) => status === SERVER_STATUS.DISCONNECTED,
|
||||
})
|
||||
|
||||
const segments = computed<DonutChartWithLegendProps['segments']>(() => [
|
||||
{
|
||||
label: t('pools-status.connected'),
|
||||
value: serversCount.value.connected,
|
||||
accent: 'success',
|
||||
},
|
||||
{
|
||||
label: t('pools-status.unreachable'),
|
||||
value: serversCount.value.unreachable,
|
||||
accent: 'warning',
|
||||
tooltip: t('pools-status.unreachable.tooltip'),
|
||||
},
|
||||
{
|
||||
label: t('pools-status.unknown'),
|
||||
value: serversCount.value.$other,
|
||||
accent: 'muted',
|
||||
tooltip: t('pools-status.unknown.tooltip'),
|
||||
},
|
||||
])
|
||||
</script>
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
.total {
|
||||
margin-left: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -41,6 +41,13 @@
|
||||
"s3-backup-repository": "S3 backup repository",
|
||||
"storage-repository": "Storage repository",
|
||||
|
||||
"pools-status": "Pools 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",
|
||||
|
||||
|
||||
@@ -41,6 +41,13 @@
|
||||
"s3-backup-repository": "Dépot de sauvegarde S3",
|
||||
"storage-repository": "Dépot de stockage",
|
||||
|
||||
"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",
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<div class="site-dashboard">
|
||||
<PoolsStatus class="pools-status" />
|
||||
<HostsStatus class="hosts-status" />
|
||||
<VmsStatus class="vms-status" />
|
||||
<ResourcesOverview class="resources-overview" />
|
||||
@@ -15,6 +16,7 @@ import BackupIssues from '@/components/site/dashboard/BackupIssues.vue'
|
||||
import Backups from '@/components/site/dashboard/Backups.vue'
|
||||
import HostsStatus from '@/components/site/dashboard/HostsStatus.vue'
|
||||
import Patches from '@/components/site/dashboard/Patches.vue'
|
||||
import PoolsStatus from '@/components/site/dashboard/PoolsStatus.vue'
|
||||
import Repositories from '@/components/site/dashboard/Repositories.vue'
|
||||
import ResourcesOverview from '@/components/site/dashboard/ResourcesOverview.vue'
|
||||
import VmsStatus from '@/components/site/dashboard/VmsStatus.vue'
|
||||
@@ -33,6 +35,10 @@ import VmsStatus from '@/components/site/dashboard/VmsStatus.vue'
|
||||
'alarms alarms alarms alarms alarms alarms patches patches';
|
||||
}
|
||||
|
||||
.pools-status {
|
||||
grid-area: pools-status;
|
||||
}
|
||||
|
||||
.hosts-status {
|
||||
grid-area: hosts-status;
|
||||
}
|
||||
|
||||
23
@xen-orchestra/web/src/stores/xo-rest-api/server.store.ts
Normal file
23
@xen-orchestra/web/src/stores/xo-rest-api/server.store.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { SERVER_STATUS } from '@/types/xo/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 }, {})
|
||||
})
|
||||
35
@xen-orchestra/web/src/types/xo/server.type.ts
Normal file
35
@xen-orchestra/web/src/types/xo/server.type.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { XoPool } from '@/types/xo/pool.type'
|
||||
import type { Branded } from '@core/types/utility.type'
|
||||
|
||||
export enum SERVER_STATUS {
|
||||
CONNECTED = 'connected',
|
||||
CONNECTING = 'connecting',
|
||||
DISCONNECTED = 'disconnected',
|
||||
}
|
||||
|
||||
type BaseServer = {
|
||||
allowUnauthorized: boolean
|
||||
enabled: boolean
|
||||
host: string
|
||||
id: Branded<'server'>
|
||||
label: string | undefined
|
||||
readOnly: boolean
|
||||
type: 'server'
|
||||
username: string
|
||||
}
|
||||
|
||||
type ConnectedServer = BaseServer & {
|
||||
status: SERVER_STATUS.CONNECTED
|
||||
poolId: XoPool['id']
|
||||
}
|
||||
|
||||
type ConnectingServer = BaseServer & {
|
||||
status: SERVER_STATUS.CONNECTING
|
||||
}
|
||||
|
||||
type DisconnectedServer = BaseServer & {
|
||||
status: SERVER_STATUS.DISCONNECTED
|
||||
error?: any
|
||||
}
|
||||
|
||||
export type XoServer = ConnectedServer | ConnectingServer | DisconnectedServer
|
||||
@@ -4,6 +4,7 @@ import type { XoHost } from '@/types/xo/host.type'
|
||||
import type { XoNetwork } from '@/types/xo/network.type'
|
||||
import type { XoPif } from '@/types/xo/pif.type'
|
||||
import type { XoPool } from '@/types/xo/pool.type'
|
||||
import type { XoServer } from '@/types/xo/server.type'
|
||||
import type { XoTask } from '@/types/xo/task.type'
|
||||
import type { XoVm } from '@/types/xo/vm.type'
|
||||
|
||||
@@ -50,4 +51,10 @@ export const xoApiDefinition = {
|
||||
fields: 'id, defaultIsLocked,name_label,nbd,tags',
|
||||
handler: (record: XoNetwork) => record,
|
||||
},
|
||||
server: {
|
||||
type: 'collection',
|
||||
path: 'servers',
|
||||
fields: '*',
|
||||
handler: (record: XoServer) => record,
|
||||
},
|
||||
} satisfies ApiDefinition
|
||||
|
||||
Reference in New Issue
Block a user