mirror of
https://github.com/vatesfr/xen-orchestra.git
synced 2026-11-09 17:06:13 -06:00
Compare commits
2 Commits
326c152fac
...
host-netwo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2dbbefad0f | ||
|
|
189840f539 |
@@ -188,7 +188,6 @@
|
||||
"start": "Start",
|
||||
"start-on-host": "Start on specific host",
|
||||
"static-ip": "Static IP",
|
||||
"status": "Status",
|
||||
"storage-usage": "Storage usage",
|
||||
"support": "Support",
|
||||
"suspend": "Suspend",
|
||||
|
||||
@@ -188,7 +188,6 @@
|
||||
"start": "Démarrer",
|
||||
"start-on-host": "Démarrer sur un hôte spécifique",
|
||||
"static-ip": "IP statique",
|
||||
"status": "Statut",
|
||||
"storage-usage": "Utilisation du stockage",
|
||||
"support": "Support",
|
||||
"suspend": "Suspendre",
|
||||
|
||||
32
@xen-orchestra/lite/src/router/host.ts
Normal file
32
@xen-orchestra/lite/src/router/host.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
export default {
|
||||
path: '/host/:uuid',
|
||||
component: () => import('@/views/host/HostRootView.vue'),
|
||||
redirect: { name: 'host.console' },
|
||||
children: [
|
||||
{
|
||||
path: 'dashboard',
|
||||
name: 'host.dashboard',
|
||||
component: () => import('@/views/host/HostDashboardView.vue'),
|
||||
},
|
||||
{
|
||||
path: 'console',
|
||||
name: 'host.console',
|
||||
component: () => import('@/views/host/HostConsoleView.vue'),
|
||||
},
|
||||
{
|
||||
path: 'network',
|
||||
name: 'host.network',
|
||||
component: () => import('@/views/host/HostNetworkView.vue'),
|
||||
},
|
||||
{
|
||||
path: 'tasks',
|
||||
name: 'host.tasks',
|
||||
component: () => import('@/views/host/HostTasksView.vue'),
|
||||
},
|
||||
{
|
||||
path: 'vms',
|
||||
name: 'host.vms',
|
||||
component: () => import('@/views/host/HostVmsView.vue'),
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import host from '@/router/host'
|
||||
import pool from '@/router/pool'
|
||||
import story from '@/router/story'
|
||||
import vm from '@/router/vm'
|
||||
@@ -25,17 +26,7 @@ const router = createRouter({
|
||||
story,
|
||||
pool,
|
||||
vm,
|
||||
{
|
||||
path: '/host/:uuid',
|
||||
component: () => import('@/views/host/HostRootView.vue'),
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'host.dashboard',
|
||||
component: () => import('@/views/host/HostDashboardView.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
host,
|
||||
{
|
||||
path: '/:pathMatch(.*)*',
|
||||
name: 'not-found',
|
||||
|
||||
11
@xen-orchestra/lite/src/views/host/HostConsoleView.vue
Normal file
11
@xen-orchestra/lite/src/views/host/HostConsoleView.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<PageUnderConstruction />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import PageUnderConstruction from '@/components/PageUnderConstruction.vue'
|
||||
import { usePageTitleStore } from '@/stores/page-title.store'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
usePageTitleStore().setTitle(useI18n().t('dashboard'))
|
||||
</script>
|
||||
19
@xen-orchestra/lite/src/views/host/HostHeader.vue
Normal file
19
@xen-orchestra/lite/src/views/host/HostHeader.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<TitleBar :icon="faServer">
|
||||
{{ name }}
|
||||
</TitleBar>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import TitleBar from '@/components/TitleBar.vue'
|
||||
import type { XenApiHost } from '@/libs/xen-api/xen-api.types'
|
||||
import { useHostStore } from '@/stores/xen-api/host.store'
|
||||
import { faServer } from '@fortawesome/free-solid-svg-icons'
|
||||
import { computed } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const { getByUuid: getHostByUuid } = useHostStore().subscribe()
|
||||
const route = useRoute()
|
||||
const host = computed(() => getHostByUuid(route.params.uuid as XenApiHost['uuid']))
|
||||
const name = computed(() => host.value?.name_label)
|
||||
</script>
|
||||
225
@xen-orchestra/lite/src/views/host/HostNetworkView.vue
Normal file
225
@xen-orchestra/lite/src/views/host/HostNetworkView.vue
Normal file
@@ -0,0 +1,225 @@
|
||||
<template>
|
||||
<div class="hostNetworkView">
|
||||
<UiTitle type="h4" class="header">
|
||||
<slot>{{ $t('pifs') }}</slot>
|
||||
<template #actions>
|
||||
<UiButton size="medium" variant="secondary" accent="info" :left-icon="faArrowsRotate">
|
||||
{{ $t('scan-pifs') }}
|
||||
</UiButton>
|
||||
</template>
|
||||
</UiTitle>
|
||||
<div class="table-container">
|
||||
<UiQuerySearchBar class="table-query" @search="(value: string) => (filter = value)" />
|
||||
<VtsTable vertical-border class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<ColumnTitle id="network" :icon="faAlignLeft">{{ $t('network') }}</ColumnTitle>
|
||||
<ColumnTitle id="device" :icon="faAlignLeft">{{ $t('device') }}</ColumnTitle>
|
||||
<ColumnTitle id="status" :icon="faPowerOff">{{ $t('status') }}</ColumnTitle>
|
||||
<ColumnTitle id="vlan" :icon="faAlignLeft">{{ $t('vlan') }}</ColumnTitle>
|
||||
<ColumnTitle id="ipAddresses" :icon="faAt">{{ $t('ip-addresses') }}</ColumnTitle>
|
||||
<ColumnTitle id="macAddress" :icon="faAt">{{ $t('mac-address') }}</ColumnTitle>
|
||||
<ColumnTitle id="ipMode" :icon="faCaretDown">{{ $t('ip-mode') }}</ColumnTitle>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="pif in pifs" :key="pif.id">
|
||||
<VtsCellObject>
|
||||
<UiObjectLink :route="`/vm/${pif.data.id}/console`">
|
||||
<template #icon>
|
||||
<UiComplexIcon size="medium">
|
||||
<VtsIcon :icon="faNetworkWired" accent="current" />
|
||||
<VtsIcon accent="success" :icon="faCircle" :overlay-icon="faCheck" />
|
||||
</UiComplexIcon>
|
||||
</template>
|
||||
{{ pif.data.name_label }}
|
||||
</UiObjectLink>
|
||||
</VtsCellObject>
|
||||
<VtsCellText>{{ pif.data.device }}</VtsCellText>
|
||||
<VtsCellObject>
|
||||
<VtsIcon
|
||||
:accent="getStatusProps(pif.data.status as NetworkStatus).accent"
|
||||
:icon="faCircle"
|
||||
:overlay-icon="getStatusProps(pif.data.status as NetworkStatus).icon"
|
||||
/>
|
||||
{{ pif.data.status }}
|
||||
</VtsCellObject>
|
||||
<VtsCellText>{{ pif.data.vlan }}</VtsCellText>
|
||||
<VtsCellText>{{ pif.data.ip }}</VtsCellText>
|
||||
<VtsCellText>{{ pif.data.mac }}</VtsCellText>
|
||||
<VtsCellText>{{ pif.data.ip_mode }}</VtsCellText>
|
||||
</tr>
|
||||
</tbody>
|
||||
</VtsTable>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import VtsCellObject from '@core/components/cell-object/VtsCellObject.vue'
|
||||
import VtsCellText from '@core/components/cell-text/VtsCellText.vue'
|
||||
import VtsIcon from '@core/components/icon/VtsIcon.vue'
|
||||
import ColumnTitle from '@core/components/table/ColumnTitle.vue'
|
||||
import VtsTable from '@core/components/table/VtsTable.vue'
|
||||
import UiButton from '@core/components/ui/button/UiButton.vue'
|
||||
import UiComplexIcon from '@core/components/ui/complex-icon/UiComplexIcon.vue'
|
||||
import UiObjectLink from '@core/components/ui/object-link/UiObjectLink.vue'
|
||||
import UiQuerySearchBar from '@core/components/ui/query-search-bar/UiQuerySearchBar.vue'
|
||||
import UiTitle from '@core/components/ui/title/UiTitle.vue'
|
||||
import { defineTree } from '@core/composables/tree/define-tree'
|
||||
import { useTreeFilter } from '@core/composables/tree-filter.composable'
|
||||
import { useTree } from '@core/composables/tree.composable'
|
||||
import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
|
||||
import {
|
||||
faAlignLeft,
|
||||
faArrowsRotate,
|
||||
faAt,
|
||||
faCaretDown,
|
||||
faCheck,
|
||||
faCircle,
|
||||
faExclamation,
|
||||
faNetworkWired,
|
||||
faPowerOff,
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
const data = [
|
||||
{
|
||||
id: 'e8ec9a13-7b65-495e-2d90-224c17e02b67',
|
||||
name_label: '[Team XCPng] - Win X centers',
|
||||
status: 'connected',
|
||||
device: 'eth1',
|
||||
vlan: 100,
|
||||
ip: '127.0.0.1',
|
||||
mac: '00:1A:2B:3C:4D:5E',
|
||||
ip_mode: 'DHCP',
|
||||
},
|
||||
{
|
||||
id: 'e40c1da3-918b-c173-506c-e8c2c069181f',
|
||||
name_label: 'AS-YA test VM pharpp_2023-10-30T15:03:17.071Z',
|
||||
status: 'connected',
|
||||
device: 'eth1',
|
||||
vlan: 101,
|
||||
ip: '127.0.0.1',
|
||||
mac: '00:1A:2B:3C:4D:5E',
|
||||
ip_mode: 'DHCP',
|
||||
},
|
||||
{
|
||||
id: '989cd0ad-17f8-c198-15c6-8549da1f3b9f',
|
||||
name_label: 'BRS - XenServer 8',
|
||||
status: 'disconnected',
|
||||
device: 'eth1',
|
||||
vlan: 100,
|
||||
ip: '127.0.0.1',
|
||||
mac: '00:1A:2B:3C:4D:5E',
|
||||
ip_mode: 'DHCP',
|
||||
},
|
||||
{
|
||||
id: 'bfbacbd4-8a09-c769-4e7e-59c2a0f77095',
|
||||
name_label: 'Debian Teddy',
|
||||
status: 'other',
|
||||
device: 'eth1',
|
||||
vlan: null,
|
||||
ip: '127.0.0.1',
|
||||
mac: '00:1A:2B:3C:4D:5E',
|
||||
ip_mode: 'DHCP',
|
||||
},
|
||||
{
|
||||
id: '03a631e2-a39e-7c63-7bb3-ac7a5ef6c47e',
|
||||
name_label: 'DML - 8.2.1 - Host 1',
|
||||
status: 'connected',
|
||||
device: 'eth1',
|
||||
vlan: 100,
|
||||
ip: '127.0.0.1',
|
||||
mac: '00:1A:2B:3C:4D:5E',
|
||||
ip_mode: 'Static',
|
||||
},
|
||||
{
|
||||
id: 'ea57eb75-c55b-d9c9-6cb4-e0ea235eb16f',
|
||||
name_label: 'ElasticSearch FMD',
|
||||
status: 'disconnected',
|
||||
device: 'eth1',
|
||||
vlan: 102,
|
||||
ip: '127.0.0.1',
|
||||
mac: '00:1A:2B:3C:4D:5E',
|
||||
ip_mode: 'DHCP',
|
||||
},
|
||||
{
|
||||
id: '559b0b63-2173-b6a1-ef65-7155d56401b6',
|
||||
name_label: 'flo-ubuntu',
|
||||
status: 'connected',
|
||||
device: 'eth1',
|
||||
vlan: 100,
|
||||
ip: '127.0.0.1',
|
||||
mac: '00:1A:2B:3C:4D:5E',
|
||||
ip_mode: 'DHCP',
|
||||
},
|
||||
{
|
||||
id: '99e196e1-33f9-461b-93e3-d70a0eb29b3e',
|
||||
name_label: 'Test BRS',
|
||||
status: 'disconnected',
|
||||
device: 'eth1',
|
||||
vlan: 100,
|
||||
ip: '127.0.0.1',
|
||||
mac: '00:1A:2B:3C:4D:5E',
|
||||
ip_mode: 'Static',
|
||||
},
|
||||
{
|
||||
id: 'cd418934-1f70-22bc-688e-eb6da266aa57',
|
||||
name_label: 'XCP-ng 8.2.1 UEFI Ext (TEe)',
|
||||
status: 'connected',
|
||||
device: 'eth1',
|
||||
vlan: 100,
|
||||
ip: '127.0.0.1',
|
||||
mac: '00:1A:2B:3C:4D:5E',
|
||||
ip_mode: 'DHCP',
|
||||
},
|
||||
{
|
||||
id: '6d9c33fc-ebec-240d-e31b-18152911795d',
|
||||
name_label: 'XCP-ng 8.3 A1 Lyon - BRS',
|
||||
status: 'connected',
|
||||
device: 'eth1',
|
||||
vlan: 100,
|
||||
ip: '127.0.0.1',
|
||||
mac: '00:1A:2B:3C:4D:5E',
|
||||
ip_mode: 'Static',
|
||||
},
|
||||
]
|
||||
|
||||
const { filter, predicate } = useTreeFilter()
|
||||
|
||||
const definitions = defineTree(data, {
|
||||
getLabel: 'name_label',
|
||||
predicate,
|
||||
})
|
||||
|
||||
const { nodes: pifs } = useTree(definitions, { expand: false })
|
||||
|
||||
type NetworkStatus = 'connected' | 'disconnected' | 'other'
|
||||
type NetworkAccent = 'success' | 'warning' | 'danger'
|
||||
|
||||
const states: Record<NetworkStatus, { icon: IconDefinition; accent: NetworkAccent }> = {
|
||||
connected: { icon: faCheck, accent: 'success' },
|
||||
disconnected: { icon: faCheck, accent: 'danger' },
|
||||
other: { icon: faExclamation, accent: 'warning' },
|
||||
}
|
||||
|
||||
const getStatusProps = (status: NetworkStatus) => states[status as NetworkStatus]
|
||||
</script>
|
||||
|
||||
<style scoped lang="postcss">
|
||||
.hostNetworkView {
|
||||
padding: 1.6rem;
|
||||
margin: 0.8rem;
|
||||
border: solid 0.1rem var(--color-neutral-border);
|
||||
border-radius: 0.8rem;
|
||||
background-color: var(--color-neutral-background-primary);
|
||||
|
||||
.table-container {
|
||||
margin-top: 2.4rem;
|
||||
|
||||
.table {
|
||||
margin-top: 2.4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,9 @@
|
||||
<template>
|
||||
<ObjectNotFoundWrapper :is-ready="isReady" :uuid-checker="hasUuid">
|
||||
<template v-if="uiStore.hasUi">
|
||||
<HostHeader />
|
||||
<HostTabBar :uuid="currentHost!.uuid" />
|
||||
</template>
|
||||
<RouterView />
|
||||
</ObjectNotFoundWrapper>
|
||||
</template>
|
||||
@@ -9,6 +13,8 @@ import ObjectNotFoundWrapper from '@/components/ObjectNotFoundWrapper.vue'
|
||||
import type { XenApiHost } from '@/libs/xen-api/xen-api.types'
|
||||
import { usePageTitleStore } from '@/stores/page-title.store'
|
||||
import { useHostStore } from '@/stores/xen-api/host.store'
|
||||
import HostHeader from '@/views/host/HostHeader.vue'
|
||||
import HostTabBar from '@/views/host/HostTabBar.vue'
|
||||
import { useUiStore } from '@core/stores/ui.store'
|
||||
import { computed, watchEffect } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
28
@xen-orchestra/lite/src/views/host/HostTabBar.vue
Normal file
28
@xen-orchestra/lite/src/views/host/HostTabBar.vue
Normal file
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<TabList>
|
||||
<RouterTab :to="{ name: 'host.dashboard', params: { uuid } }">
|
||||
{{ $t('dashboard') }}
|
||||
</RouterTab>
|
||||
<RouterTab :to="{ name: 'host.console', params: { uuid } }" disabled>
|
||||
{{ $t('console') }}
|
||||
</RouterTab>
|
||||
<RouterTab :to="{ name: 'host.network', params: { uuid } }">
|
||||
{{ $t('network') }}
|
||||
</RouterTab>
|
||||
<RouterTab :to="{ name: 'host.tasks', params: { uuid } }" disabled>
|
||||
{{ $t('tasks') }}
|
||||
</RouterTab>
|
||||
<RouterTab :to="{ name: 'host.vms', params: { uuid } }" disabled>
|
||||
{{ $t('vms') }}
|
||||
</RouterTab>
|
||||
</TabList>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import RouterTab from '@/components/RouterTab.vue'
|
||||
import TabList from '@core/components/tab/TabList.vue'
|
||||
|
||||
defineProps<{
|
||||
uuid: string
|
||||
}>()
|
||||
</script>
|
||||
11
@xen-orchestra/lite/src/views/host/HostTasksView.vue
Normal file
11
@xen-orchestra/lite/src/views/host/HostTasksView.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<PageUnderConstruction />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import PageUnderConstruction from '@/components/PageUnderConstruction.vue'
|
||||
import { usePageTitleStore } from '@/stores/page-title.store'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
usePageTitleStore().setTitle(useI18n().t('dashboard'))
|
||||
</script>
|
||||
11
@xen-orchestra/lite/src/views/host/HostVmsView.vue
Normal file
11
@xen-orchestra/lite/src/views/host/HostVmsView.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<PageUnderConstruction />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import PageUnderConstruction from '@/components/PageUnderConstruction.vue'
|
||||
import { usePageTitleStore } from '@/stores/page-title.store'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
usePageTitleStore().setTitle(useI18n().t('dashboard'))
|
||||
</script>
|
||||
@@ -72,6 +72,7 @@ const classNames = computed(() => [
|
||||
border-width: 0.1rem;
|
||||
outline: none;
|
||||
border-style: solid;
|
||||
white-space: nowrap;
|
||||
|
||||
&.lock {
|
||||
cursor: default;
|
||||
|
||||
@@ -88,6 +88,7 @@ const id = computed(() => uniqueId('input-'))
|
||||
/* IMPLEMENTATION */
|
||||
.ui-input {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
.before + .input {
|
||||
padding-inline-start: 4.8rem;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<UiInput
|
||||
:id
|
||||
v-model="value"
|
||||
class="ui-query-search-bar-input"
|
||||
:aria-label="uiStore.isMobile ? $t('core.query-search-bar.label') : undefined"
|
||||
:icon="uiStore.isDesktop ? faMagnifyingGlass : undefined"
|
||||
:placeholder="$t('core.query-search-bar.placeholder')"
|
||||
@@ -62,6 +63,7 @@ const value = ref<string>('')
|
||||
|
||||
.label {
|
||||
color: var(--color-neutral-txt-secondary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -23,10 +23,10 @@ const slots = defineSlots<{
|
||||
align-items: center;
|
||||
gap: 2.4rem;
|
||||
padding-block-end: 0.4rem;
|
||||
border-bottom: 0.1rem solid var(--color-normal-txt-base);
|
||||
border-bottom: 0.1rem solid var(--color-info-txt-base);
|
||||
|
||||
.label {
|
||||
color: var(--color-normal-txt-base);
|
||||
color: var(--color-info-txt-base);
|
||||
}
|
||||
|
||||
.actions {
|
||||
|
||||
@@ -40,11 +40,15 @@
|
||||
"dark-mode.auto": "Auto dark mode",
|
||||
|
||||
"dashboard": "Dashboard",
|
||||
"device": "Device",
|
||||
"documentation-name": "{name} documentation",
|
||||
"hosts": "Hosts",
|
||||
"ip-addresses": "IP Adresses",
|
||||
"ip-mode": "IP mode",
|
||||
"learn-more": "Learn more",
|
||||
"loading-in-progress": "Loading in progress…",
|
||||
"log-out": "Log out",
|
||||
"mac-address": "MAC address",
|
||||
"master": "Primary host",
|
||||
"n-vms": "1 VM | {n} VMs",
|
||||
"network": "Network",
|
||||
@@ -52,11 +56,14 @@
|
||||
"object-not-found": "Object {id} can't be found…",
|
||||
"other": "Other",
|
||||
"patches": "Patches",
|
||||
"pifs": "PIFs",
|
||||
"power-on-vm-for-console": "Power on your VM to access its console",
|
||||
"power-on-host-for-console": "Power on your host to access its console",
|
||||
"running-vm": "Running VM | Running VMs",
|
||||
"scan-pifs": "Scan PIFs",
|
||||
"see-all": "See all",
|
||||
"stats": "Stats",
|
||||
"status": "Status",
|
||||
"storage": "Storage",
|
||||
"support-name": "{name} pro support",
|
||||
"system": "System",
|
||||
@@ -72,5 +79,6 @@
|
||||
|
||||
"total": "Total",
|
||||
"total-cpus": "Total CPUs",
|
||||
"vlan": "VLAN",
|
||||
"vms": "VMs"
|
||||
}
|
||||
|
||||
@@ -40,11 +40,15 @@
|
||||
"dark-mode.auto": "Mode sombre automatique",
|
||||
|
||||
"dashboard": "Tableau de bord",
|
||||
"device": "Appareil",
|
||||
"documentation-name": "Documentation {name}",
|
||||
"hosts": "Hôtes",
|
||||
"ip-addresses": "Adresses IP",
|
||||
"ip-mode": "Mode IP",
|
||||
"learn-more": "En savoir plus",
|
||||
"loading-in-progress": "Chargement en cours…",
|
||||
"log-out": "Se déconnecter",
|
||||
"mac-address": "Adresse MAC",
|
||||
"master": "Hôte primaire",
|
||||
"n-vms": "1 VM | {n} VMs",
|
||||
"network": "Réseau",
|
||||
@@ -52,11 +56,14 @@
|
||||
"object-not-found": "L'objet {id} est introuvable…",
|
||||
"other": "Autre",
|
||||
"patches": "Patches",
|
||||
"pifs": "PIFs",
|
||||
"power-on-vm-for-console": "Allumez votre VM pour accéder à sa console",
|
||||
"power-on-host-for-console": "Allumez votre hôte pour accéder à sa console",
|
||||
"running-vm": "VM en cours d'exécution | VMs en cours d'exécution",
|
||||
"scan-pifs": "Scanner les PIFs",
|
||||
"see-all": "Voir tout",
|
||||
"stats": "Stats",
|
||||
"status": "Statut",
|
||||
"storage": "Stockage",
|
||||
"support-name": "Support pro {name}",
|
||||
"system": "Système",
|
||||
@@ -72,5 +79,6 @@
|
||||
|
||||
"total": "Total",
|
||||
"total-cpus": "Total CPUs",
|
||||
"vlan": "VLAN",
|
||||
"vms": "VMs"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user