Compare commits

...

17 Commits

Author SHA1 Message Date
Thierry
e55e43157a filter out connected servers which have no corresponding pool 2024-12-18 11:51:12 +01:00
Thierry
c6f7f53d1d rebase on master 2024-12-17 15:19:15 +01:00
Thierry
1fd3bb86ec update pools status on dashboard 2024-12-17 15:12:42 +01:00
P4l0m4
c66ccf36e1 update locales and store 2024-12-17 15:12:42 +01:00
P4l0m4
fbfd170d0e update to match parent branch 2024-12-17 15:12:42 +01:00
P4l0m4
55e4919902 feat(xo-web): add pool status component to xo6 dashboard 2024-12-17 15:12:42 +01:00
Thierry
a993b5dec5 update HostsStatus component. Fix HOST_POWER_STATE enum. 2024-12-17 15:12:42 +01:00
P4l0m4
050f31a3d6 update to match parent PR 2024-12-17 15:12:42 +01:00
P4l0m4
9d27020135 feat(xo-web): add host status to xo6 dashboard 2024-12-17 15:12:42 +01:00
P4l0m4
69c082a917 feat(xo-web): add donut chart with legends component 2024-12-17 15:12:42 +01:00
Thierry
0427e09738 better directory structure 2024-12-17 15:12:42 +01:00
Thierry
2515311c6e update VmsStatus + site dashboard 2024-12-17 15:12:41 +01:00
P4l0m4
6d623666ca update to match parent PR 2024-12-17 15:12:41 +01:00
P4l0m4
18bdc3971c feat(xo-web): add donut chart with legends component 2024-12-17 15:12:41 +01:00
Thierry
cf11ffcc11 update DonutChartWithLegend 2024-12-17 15:12:41 +01:00
P4l0m4
8834b25926 add types 2024-12-17 15:12:41 +01:00
P4l0m4
b053eef0a5 feat(xo-core): add donut with legends component to xo6 2024-12-17 15:12:41 +01:00
7 changed files with 146 additions and 0 deletions

View File

@@ -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>

View File

@@ -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",

View File

@@ -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",

View File

@@ -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;
}

View 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 }, {})
})

View 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

View File

@@ -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