feat(xo-stack): update system pages layout (#9746)

This commit is contained in:
OlivierFL
2026-05-05 09:26:19 +02:00
committed by GitHub
parent 225d1699e8
commit ef1fe13667
73 changed files with 1327 additions and 948 deletions

View File

@@ -1,5 +1,9 @@
# ChangeLog
## **next**
- [System] Update system pages layout ([user feedback](https://feedback.vates.tech/posts/37/xo6-ui-very-messy-columns-width-in-vm-system-far-better-in-xo5)) (PR [#9746](https://github.com/vatesfr/xen-orchestra/pull/9746))
## **0.20.0** (2026-04-01)
- [VM/New] Added secureBoot support (PR [#9423](https://github.com/vatesfr/xen-orchestra/pull/9423))

View File

@@ -1,15 +1,15 @@
<template>
<VtsQuickInfoCard class="host-dashboard-quick-info" :loading="!isReady">
<VtsQuickInfoColumn>
<VtsQuickInfoRow :label="t('state')">
<VtsKeyValueList>
<VtsKeyValueRow :label="t('state')">
<template #value>
<VtsIcon :name="powerState.icon" size="medium" />
{{ powerState.text }}
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('ip-address')" :value="host.address" />
<VtsQuickInfoRow :label="t('started')" :value="isRunning ? relativeStartTime : undefined" />
<VtsQuickInfoRow :label="t('master')">
</VtsKeyValueRow>
<VtsKeyValueRow :label="t('ip-address')" :value="host.address" />
<VtsKeyValueRow :label="t('started')" :value="isRunning ? relativeStartTime : undefined" />
<VtsKeyValueRow :label="t('master')">
<template #value>
<template v-if="isMaster">
<VtsIcon v-tooltip="t('master')" name="status:primary-circle" size="medium" />
@@ -24,31 +24,31 @@
{{ masterHost.name_label }}
</UiLink>
</template>
</VtsQuickInfoRow>
</VtsQuickInfoColumn>
<VtsQuickInfoColumn>
<VtsQuickInfoRow :label="t('uuid')" :value="host.uuid" />
<VtsQuickInfoRow :label="t('description')" :value="host.name_description" />
<VtsQuickInfoRow :label="t('version')" :value="host.software_version.product_version" />
<VtsQuickInfoRow
</VtsKeyValueRow>
</VtsKeyValueList>
<VtsKeyValueList>
<VtsKeyValueRow :label="t('uuid')" :value="host.uuid" />
<VtsKeyValueRow :label="t('description')" :value="host.name_description" />
<VtsKeyValueRow :label="t('version')" :value="host.software_version.product_version" />
<VtsKeyValueRow
:label="t('hardware')"
:value="`${host.bios_strings['system-manufacturer']} (${host.bios_strings['system-product-name']})`"
/>
</VtsQuickInfoColumn>
<VtsQuickInfoColumn>
<VtsQuickInfoRow
</VtsKeyValueList>
<VtsKeyValueList>
<VtsKeyValueRow
:label="t('cores-with-sockets')"
:value="`${host.cpu_info.cpu_count} (${host.cpu_info.socket_count})`"
/>
<VtsQuickInfoRow :label="t('ram')" :value="`${ram?.value} ${ram?.prefix}`" />
<VtsQuickInfoRow :label="t('tags')">
<VtsKeyValueRow :label="t('ram')" :value="`${ram?.value} ${ram?.prefix}`" />
<VtsKeyValueRow :label="t('tags')">
<template #value>
<UiTagsList v-if="host.tags.length">
<UiTag v-for="tag in host.tags" :key="tag" accent="info" variant="secondary">{{ tag }}</UiTag>
</UiTagsList>
</template>
</VtsQuickInfoRow>
</VtsQuickInfoColumn>
</VtsKeyValueRow>
</VtsKeyValueList>
</VtsQuickInfoCard>
</template>
@@ -59,9 +59,9 @@ import { useHostStore } from '@/stores/xen-api/host.store.ts'
import { usePoolStore } from '@/stores/xen-api/pool.store.ts'
import type { IconName } from '@core/icons'
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import VtsKeyValueList from '@core/components/key-value-list/VtsKeyValueList.vue'
import VtsKeyValueRow from '@core/components/key-value-row/VtsKeyValueRow.vue'
import VtsQuickInfoCard from '@core/components/quick-info-card/VtsQuickInfoCard.vue'
import VtsQuickInfoColumn from '@core/components/quick-info-column/VtsQuickInfoColumn.vue'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiTag from '@core/components/ui/tag/UiTag.vue'
import UiTagsList from '@core/components/ui/tag/UiTagsList.vue'

View File

@@ -3,51 +3,58 @@
<UiTitle>
{{ t('general-information') }}
</UiTitle>
<VtsQuickInfoRow :label="t('name')" :value="host.name_label" />
<VtsQuickInfoRow :label="t('uuid')" :value="host.uuid" />
<VtsQuickInfoRow :label="t('description')" :value="host.name_description" />
<VtsQuickInfoRow :label="t('tags')">
<template v-if="host.tags.length > 0" #value>
<UiTagsList class="value">
<UiTag v-for="tag in host.tags" :key="tag" accent="info" variant="secondary">
{{ tag }}
</UiTag>
</UiTagsList>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('status')">
<template #value>
<VtsStatus :status="host.enabled" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('pool')">
<template v-if="pool !== undefined" #value>
<UiLink size="medium" :to="`/pool/${pool.uuid}/`" icon="object:pool">
{{ pool.name_label }}
</UiLink>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('master')">
<template #value>
<template v-if="isMaster">
<VtsIcon v-tooltip="t('master')" name="status:primary-circle" size="medium" />
{{ t('this-host') }}
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('name')" :value="host.name_label" />
<VtsTabularKeyValueRow :label="t('uuid')" :value="host.uuid" />
<VtsTabularKeyValueRow :label="t('description')" :value="host.name_description" />
<VtsTabularKeyValueRow :label="t('tags')">
<template v-if="host.tags.length > 0" #value>
<UiTagsList class="value">
<UiTag v-for="tag in host.tags" :key="tag" accent="info" variant="secondary">
{{ tag }}
</UiTag>
</UiTagsList>
</template>
<UiLink v-else-if="masterHost !== undefined" size="medium" :to="`/host/${masterHost.uuid}/`" icon="object:host">
{{ masterHost.name_label }}
</UiLink>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('started')">
<template v-if="isRunning" #value>
<VtsRelativeTime :date="host.other_config.boot_time * 1000" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('power-on-mode')">
<template #value>
<VtsStatus :status="host.power_on_mode !== ''" />
</template>
</VtsQuickInfoRow>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('status')">
<template #value>
<VtsStatus :status="host.enabled" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('pool')">
<template v-if="pool !== undefined" #value>
<UiLink size="medium" :to="`/pool/${pool.uuid}/`" icon="object:pool">
{{ pool.name_label }}
</UiLink>
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('master')">
<template #value>
<template v-if="isMaster">
<VtsIcon v-tooltip="t('master')" name="status:primary-circle" size="medium" />
{{ t('this-host') }}
</template>
<UiLink
v-else-if="masterHost !== undefined"
size="medium"
:to="`/host/${masterHost.uuid}/`"
icon="object:host"
>
{{ masterHost.name_label }}
</UiLink>
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('started')">
<template v-if="isRunning" #value>
<VtsRelativeTime :date="host.other_config.boot_time * 1000" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('power-on-mode')">
<template #value>
<VtsStatus :status="host.power_on_mode !== ''" />
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</UiCard>
</template>
@@ -56,9 +63,10 @@ import type { XenApiHost } from '@/libs/xen-api/xen-api.types.ts'
import { useHostMetricsStore } from '@/stores/xen-api/host-metrics.store.ts'
import { usePoolStore } from '@/stores/xen-api/pool.store.ts'
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsRelativeTime from '@core/components/relative-time/VtsRelativeTime.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiTag from '@core/components/ui/tag/UiTag.vue'

View File

@@ -3,26 +3,31 @@
<UiTitle>
{{ t('hardware-specifications') }}
</UiTitle>
<VtsQuickInfoRow
:label="t('manufacturer-info')"
:value="`${host.bios_strings['system-manufacturer']} (${host.bios_strings['system-product-name']})`"
/>
<VtsQuickInfoRow
:label="t('bios-info')"
:value="`${host.bios_strings['bios-vendor']} (${host.bios_strings['bios-version']})`"
/>
<VtsQuickInfoRow :label="t('cpu-model')" :value="host.cpu_info.modelname" />
<VtsQuickInfoRow :label="t('core-socket')" :value="`${host.cpu_info.cpu_count} (${host.cpu_info.socket_count})`" />
<VtsQuickInfoRow :label="t('gpus')">
<template v-if="isReady" #value>
<template v-if="devicesNames">
{{ devicesNames }}
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow
:label="t('manufacturer-info')"
:value="`${host.bios_strings['system-manufacturer']} (${host.bios_strings['system-product-name']})`"
/>
<VtsTabularKeyValueRow
:label="t('bios-info')"
:value="`${host.bios_strings['bios-vendor']} (${host.bios_strings['bios-version']})`"
/>
<VtsTabularKeyValueRow :label="t('cpu-model')" :value="host.cpu_info.modelname" />
<VtsTabularKeyValueRow
:label="t('core-socket')"
:value="`${host.cpu_info.cpu_count} (${host.cpu_info.socket_count})`"
/>
<VtsTabularKeyValueRow :label="t('gpus')">
<template v-if="isReady" #value>
<template v-if="devicesNames">
{{ devicesNames }}
</template>
<template v-else>
{{ t('none') }}
</template>
</template>
<template v-else>
{{ t('none') }}
</template>
</template>
</VtsQuickInfoRow>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</UiCard>
</template>
@@ -30,7 +35,8 @@
import type { XenApiHost } from '@/libs/xen-api/xen-api.types.ts'
import { usePciStore } from '@/stores/xen-api/pci.store.ts'
import { usePgpuStore } from '@/stores/xen-api/pgpu.store.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { logicAnd } from '@vueuse/math'

View File

@@ -3,14 +3,17 @@
<UiTitle>
{{ t('licensing') }}
</UiTitle>
<VtsQuickInfoRow />
<VtsQuickInfoRow />
<VtsQuickInfoRow />
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow />
<VtsTabularKeyValueRow />
<VtsTabularKeyValueRow />
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { useI18n } from 'vue-i18n'

View File

@@ -3,21 +3,24 @@
<UiTitle>
{{ t('networking') }}
</UiTitle>
<VtsQuickInfoRow :label="t('ip-address')" :value="host.address" />
<VtsQuickInfoRow :label="t('remote-syslog')" :value="host.logging.syslog_destination" />
<VtsQuickInfoRow :label="t('iscsi-iqn')" :value="host.iscsi_iqn" />
<VtsQuickInfoRow :label="t('multi-pathing')">
<template #value>
<VtsStatus :status="host.multipathing" />
</template>
</VtsQuickInfoRow>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('ip-address')" :value="host.address" />
<VtsTabularKeyValueRow :label="t('remote-syslog')" :value="host.logging.syslog_destination" />
<VtsTabularKeyValueRow :label="t('iscsi-iqn')" :value="host.iscsi_iqn" />
<VtsTabularKeyValueRow :label="t('multi-pathing')">
<template #value>
<VtsStatus :status="host.multipathing" />
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import type { XenApiHost } from '@/libs/xen-api/xen-api.types.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { useI18n } from 'vue-i18n'

View File

@@ -3,14 +3,17 @@
<UiTitle>
{{ t('resource-management') }}
</UiTitle>
<VtsQuickInfoRow :label="t('control-domain-memory')" :value="controllerMemory" />
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('control-domain-memory')" :value="controllerMemory" />
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import type { XenApiHost } from '@/libs/xen-api/xen-api.types.ts'
import { useControlDomainStore } from '@/stores/xen-api/control-domain.store.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { formatSize } from '@core/utils/size.util.ts'

View File

@@ -3,21 +3,24 @@
<UiTitle>
{{ t('software-tooling') }}
</UiTitle>
<VtsQuickInfoRow :label="t('version')" :value="host.software_version.product_version" />
<VtsQuickInfoRow :label="t('build-number')" :value="host.software_version.build_number" />
<VtsQuickInfoRow :label="t('toolstack-uptime')">
<template v-if="isRunning" #value>
<VtsRelativeTime :date="Number(host.other_config.agent_start_time) * 1000" />
</template>
</VtsQuickInfoRow>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('version')" :value="host.software_version.product_version" />
<VtsTabularKeyValueRow :label="t('build-number')" :value="host.software_version.build_number" />
<VtsTabularKeyValueRow :label="t('toolstack-uptime')">
<template v-if="isRunning" #value>
<VtsRelativeTime :date="Number(host.other_config.agent_start_time) * 1000" />
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import type { XenApiHost } from '@/libs/xen-api/xen-api.types.ts'
import { useHostMetricsStore } from '@/stores/xen-api/host-metrics.store.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsRelativeTime from '@core/components/relative-time/VtsRelativeTime.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { computed } from 'vue'

View File

@@ -3,24 +3,27 @@
<UiTitle>
{{ t('general-information') }}
</UiTitle>
<VtsQuickInfoRow :label="t('name')" :value="pool.name_label" />
<VtsQuickInfoRow :label="t('uuid')" :value="pool.uuid" />
<VtsQuickInfoRow :label="t('description')" :value="pool.name_description" />
<VtsQuickInfoRow :label="t('tags')">
<template v-if="pool.tags.length > 0" #value>
<UiTagsList>
<UiTag v-for="tag in pool.tags" :key="tag" accent="info" variant="secondary">
{{ tag }}
</UiTag>
</UiTagsList>
</template>
</VtsQuickInfoRow>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('name')" :value="pool.name_label" />
<VtsTabularKeyValueRow :label="t('uuid')" :value="pool.uuid" />
<VtsTabularKeyValueRow :label="t('description')" :value="pool.name_description" />
<VtsTabularKeyValueRow :label="t('tags')">
<template v-if="pool.tags.length > 0" #value>
<UiTagsList>
<UiTag v-for="tag in pool.tags" :key="tag" accent="info" variant="secondary">
{{ tag }}
</UiTag>
</UiTagsList>
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import type { XenApiPool } from '@/libs/xen-api/xen-api.types'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTag from '@core/components/ui/tag/UiTag.vue'
import UiTagsList from '@core/components/ui/tag/UiTagsList.vue'

View File

@@ -5,31 +5,33 @@
</UiTitle>
<VtsStateHero v-if="!isReady" format="card" type="busy" size="medium" />
<template v-else>
<VtsQuickInfoRow :label="t('master')">
<template #value>
<UiLink v-if="masterHost" icon="object:host" :to="`/host/${masterHost.uuid}/`" size="medium">
{{ masterHost.name_label }}
</UiLink>
<template v-else>
{{ t('none') }}
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('master')">
<template #value>
<UiLink v-if="masterHost" icon="object:host" :to="`/host/${masterHost.uuid}/`" size="medium">
{{ masterHost.name_label }}
</UiLink>
<template v-else>
{{ t('none') }}
</template>
</template>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('auto-power')">
<template #value>
<VtsStatus :status="pool.other_config.auto_poweron === 'true'" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('high-availability')">
<template #value>
<VtsStatus :status="Boolean(pool.ha_enabled)" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('migration-compression')">
<template #value>
<VtsStatus :status="pool.migration_compression ?? false" />
</template>
</VtsQuickInfoRow>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('auto-power')">
<template #value>
<VtsStatus :status="pool.other_config.auto_poweron === 'true'" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('high-availability')">
<template #value>
<VtsStatus :status="Boolean(pool.ha_enabled)" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('migration-compression')">
<template #value>
<VtsStatus :status="pool.migration_compression ?? false" />
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</template>
</UiCard>
</template>
@@ -37,9 +39,10 @@
<script setup lang="ts">
import type { XenApiPool } from '@/libs/xen-api/xen-api.types'
import { usePoolStore } from '@/stores/xen-api/pool.store'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsStateHero from '@core/components/state-hero/VtsStateHero.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'

View File

@@ -5,21 +5,23 @@
</UiTitle>
<VtsStateHero v-if="!isReady" format="card" type="busy" size="medium" />
<template v-else>
<VtsQuickInfoRow :label="t('backup-network')">
<template #value>
<UiLink
v-if="backupNetwork !== undefined"
:to="`/pool/${pool.uuid}/network?id=${backupNetwork.uuid}`"
icon="object:network"
size="medium"
>
{{ backupNetwork.name_label }}
</UiLink>
<template v-else>
{{ t('none') }}
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('backup-network')">
<template #value>
<UiLink
v-if="backupNetwork !== undefined"
:to="`/pool/${pool.uuid}/network?id=${backupNetwork.uuid}`"
icon="object:network"
size="medium"
>
{{ backupNetwork.name_label }}
</UiLink>
<template v-else>
{{ t('none') }}
</template>
</template>
</template>
</VtsQuickInfoRow>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</template>
</UiCard>
</template>
@@ -27,8 +29,9 @@
<script setup lang="ts">
import type { XenApiNetwork, XenApiPool } from '@/libs/xen-api/xen-api.types'
import { useNetworkStore } from '@/stores/xen-api/network.store'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsStateHero from '@core/components/state-hero/VtsStateHero.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'

View File

@@ -5,52 +5,54 @@
</UiTitle>
<VtsStateHero v-if="!isReady" format="card" type="busy" size="medium" />
<template v-else>
<VtsQuickInfoRow :label="t('default-storage-repository')">
<template #value>
<template v-if="defaultSr">
<VtsIcon name="object:sr" size="medium" />
{{ defaultSr.name_label }}
</template>
<template v-else>
{{ t('none') }}
</template>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('suspend-storage-repository')">
<template #value>
<template v-if="suspendSr">
<VtsIcon name="object:sr" size="medium" />
{{ suspendSr.name_label }}
</template>
<template v-else>
{{ t('none') }}
</template>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('crash-dump-storage-repository')">
<template #value>
<template v-if="crashDumpSr">
<VtsIcon name="object:sr" size="medium" />
{{ crashDumpSr.name_label }}
</template>
<template v-else>
{{ t('none') }}
</template>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('heartbeat-storage-repository')">
<template #value>
<ul v-if="haSrs !== undefined && haSrs.length > 0">
<li v-for="haSr in haSrs" :key="haSr.uuid">
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('default-storage-repository')">
<template #value>
<template v-if="defaultSr">
<VtsIcon name="object:sr" size="medium" />
{{ haSr.name_label }}
</li>
</ul>
<template v-else>
{{ t('none') }}
{{ defaultSr.name_label }}
</template>
<template v-else>
{{ t('none') }}
</template>
</template>
</template>
</VtsQuickInfoRow>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('suspend-storage-repository')">
<template #value>
<template v-if="suspendSr">
<VtsIcon name="object:sr" size="medium" />
{{ suspendSr.name_label }}
</template>
<template v-else>
{{ t('none') }}
</template>
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('crash-dump-storage-repository')">
<template #value>
<template v-if="crashDumpSr">
<VtsIcon name="object:sr" size="medium" />
{{ crashDumpSr.name_label }}
</template>
<template v-else>
{{ t('none') }}
</template>
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('heartbeat-storage-repository')">
<template #value>
<ul v-if="haSrs !== undefined && haSrs.length > 0">
<li v-for="haSr in haSrs" :key="haSr.uuid">
<VtsIcon name="object:sr" size="medium" />
{{ haSr.name_label }}
</li>
</ul>
<template v-else>
{{ t('none') }}
</template>
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</template>
</UiCard>
</template>
@@ -60,8 +62,9 @@ import type { XenApiPool, XenApiSr } from '@/libs/xen-api/xen-api.types'
import { useSrStore } from '@/stores/xen-api/sr.store'
import { useVdiStore } from '@/stores/xen-api/vdi.store'
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsStateHero from '@core/components/state-hero/VtsStateHero.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { computed } from 'vue'

View File

@@ -1,21 +1,21 @@
<template>
<VtsQuickInfoCard class="vm-dashboard-quick-info" :loading="!isReady">
<VtsQuickInfoColumn>
<VtsQuickInfoRow :label="t('state')">
<VtsKeyValueList>
<VtsKeyValueRow :label="t('state')">
<template #value>
<span class="power-state">
<VtsIcon :name="powerState.icon" size="medium" />
{{ powerState.text }}
</span>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('ip-address')" :value="mainIpAddress" />
<VtsQuickInfoRow :label="t('created-on')" :value="installDateFormatted" />
<VtsQuickInfoRow :label="t('started')" :value="relativeStartTime" />
</VtsQuickInfoColumn>
<VtsQuickInfoColumn>
<VtsQuickInfoRow :label="t('uuid')" :value="vm.uuid" />
<VtsQuickInfoRow :label="t('host')">
</VtsKeyValueRow>
<VtsKeyValueRow :label="t('ip-address')" :value="mainIpAddress" />
<VtsKeyValueRow :label="t('created-on')" :value="installDateFormatted" />
<VtsKeyValueRow :label="t('started')" :value="relativeStartTime" />
</VtsKeyValueList>
<VtsKeyValueList>
<VtsKeyValueRow :label="t('uuid')" :value="vm.uuid" />
<VtsKeyValueRow :label="t('host')">
<template #value>
<span v-if="host" class="host-name">
<UiLink :to="`/host/${host.uuid}`" size="medium" :icon="`object:host:${hostPowerState}`">
@@ -27,25 +27,25 @@
{{ t('none') }}
</span>
</template>
</VtsQuickInfoRow>
</VtsQuickInfoColumn>
<VtsQuickInfoColumn>
<VtsQuickInfoRow :label="t('description')" :value="vm.name_description" />
<VtsQuickInfoRow :label="t('os-name')" :value="osVersion" />
<VtsQuickInfoRow :label="t('virtualization-type')" :value="virtualizationType" />
<VtsQuickInfoRow :label="t('guest-tools')" :value="guestTools" />
</VtsQuickInfoColumn>
<VtsQuickInfoColumn>
<VtsQuickInfoRow :label="t('vcpus')" :value="String(vm.VCPUs_at_startup)" />
<VtsQuickInfoRow :label="t('ram')" :value="`${ram.value} ${ram.prefix}`" />
<VtsQuickInfoRow :label="t('tags')">
</VtsKeyValueRow>
</VtsKeyValueList>
<VtsKeyValueList>
<VtsKeyValueRow :label="t('description')" :value="vm.name_description" />
<VtsKeyValueRow :label="t('os-name')" :value="osVersion" />
<VtsKeyValueRow :label="t('virtualization-type')" :value="virtualizationType" />
<VtsKeyValueRow :label="t('guest-tools')" :value="guestTools" />
</VtsKeyValueList>
<VtsKeyValueList>
<VtsKeyValueRow :label="t('vcpus')" :value="String(vm.VCPUs_at_startup)" />
<VtsKeyValueRow :label="t('ram')" :value="`${ram.value} ${ram.prefix}`" />
<VtsKeyValueRow :label="t('tags')">
<template #value>
<UiTagsList v-if="vm.tags.length > 0">
<UiTag v-for="tag in vm.tags" :key="tag" accent="info" variant="secondary">{{ tag }}</UiTag>
</UiTagsList>
</template>
</VtsQuickInfoRow>
</VtsQuickInfoColumn>
</VtsKeyValueRow>
</VtsKeyValueList>
</VtsQuickInfoCard>
</template>
@@ -58,9 +58,9 @@ import { useVmGuestMetricsStore } from '@/stores/xen-api/vm-guest-metrics.store.
import { useVmMetricsStore } from '@/stores/xen-api/vm-metrics.store.ts'
import { useVmStore } from '@/stores/xen-api/vm.store.ts'
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import VtsKeyValueList from '@core/components/key-value-list/VtsKeyValueList.vue'
import VtsKeyValueRow from '@core/components/key-value-row/VtsKeyValueRow.vue'
import VtsQuickInfoCard from '@core/components/quick-info-card/VtsQuickInfoCard.vue'
import VtsQuickInfoColumn from '@core/components/quick-info-column/VtsQuickInfoColumn.vue'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiTag from '@core/components/ui/tag/UiTag.vue'
import UiTagsList from '@core/components/ui/tag/UiTagsList.vue'

View File

@@ -3,26 +3,29 @@
<UiTitle>
{{ t('general-information') }}
</UiTitle>
<VtsQuickInfoRow :label="t('name')" :value="vm.name_label" />
<VtsQuickInfoRow :label="t('id')" :value="vm.uuid" />
<VtsQuickInfoRow :label="t('description')" :value="vm.name_description" />
<VtsQuickInfoRow :label="t('tags')">
<template v-if="vm.tags.length > 0" #value>
<UiTagsList>
<UiTag v-for="tag in vm.tags" :key="tag" accent="info" variant="secondary">{{ tag }}</UiTag>
</UiTagsList>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('os-name')" :value="guestMetrics?.os_version.name" />
<VtsQuickInfoRow :label="t('os-kernel')" :value="guestMetrics?.os_version.uname" />
<VtsQuickInfoRow :label="t('management-agent-version')" :value="pvVersion" />
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('name')" :value="vm.name_label" />
<VtsTabularKeyValueRow :label="t('id')" :value="vm.uuid" />
<VtsTabularKeyValueRow :label="t('description')" :value="vm.name_description" />
<VtsTabularKeyValueRow :label="t('tags')">
<template v-if="vm.tags.length > 0" #value>
<UiTagsList>
<UiTag v-for="tag in vm.tags" :key="tag" accent="info" variant="secondary">{{ tag }}</UiTag>
</UiTagsList>
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('os-name')" :value="guestMetrics?.os_version.name" />
<VtsTabularKeyValueRow :label="t('os-kernel')" :value="guestMetrics?.os_version.uname" />
<VtsTabularKeyValueRow :label="t('management-agent-version')" :value="pvVersion" />
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import type { XenApiVm } from '@/libs/xen-api/xen-api.types'
import { useVmGuestMetricsStore } from '@/stores/xen-api/vm-guest-metrics.store'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTag from '@core/components/ui/tag/UiTag.vue'
import UiTagsList from '@core/components/ui/tag/UiTagsList.vue'

View File

@@ -3,23 +3,26 @@
<UiTitle>
{{ t('graphics-display') }}
</UiTitle>
<VtsQuickInfoRow :label="t('vga')">
<template #value>
<VtsStatus :status="vm.platform.vga === 'std'" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('video-ram')">
<template v-if="videoRamValue?.value" #value>
{{ `${videoRamValue.value} ${videoRamValue.prefix || t('bytes:mi')}` }}
</template>
</VtsQuickInfoRow>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('vga')">
<template #value>
<VtsStatus :status="vm.platform.vga === 'std'" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('video-ram')">
<template v-if="videoRamValue?.value" #value>
{{ `${videoRamValue.value} ${videoRamValue.prefix || t('bytes:mi')}` }}
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import type { XenApiVm } from '@/libs/xen-api/xen-api.types'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { formatSizeRaw } from '@core/utils/size.util'

View File

@@ -3,35 +3,37 @@
<UiTitle>
{{ t('vm-management') }}
</UiTitle>
<VtsQuickInfoRow :label="t('high-availability')">
<template #value>
<VtsStatus :status="vm.ha_restart_priority !== ''" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('affinity-host')">
<template v-if="affinityHost?.uuid" #value>
<UiLink icon="object:host" :to="`/host/${affinityHost.uuid}`" size="medium">
{{ affinityHost.name_label }}
</UiLink>
</template>
<template v-else #value>{{ t('none') }}</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('protect-from-accidental-deletion')">
<template #value>
<VtsStatus :status="vm.blocked_operations?.destroy === 'true'" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('protect-from-accidental-shutdown')">
<template #value>
<VtsStatus :status="isProtectedFromAccidentalShutdown" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('auto-power')">
<template #value>
<VtsStatus :status="vm.other_config.auto_poweron === 'true'" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('start-delay')" :value="formattedStartDelay" />
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('high-availability')">
<template #value>
<VtsStatus :status="vm.ha_restart_priority !== ''" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('affinity-host')">
<template v-if="affinityHost?.uuid" #value>
<UiLink icon="object:host" :to="`/host/${affinityHost.uuid}`" size="medium">
{{ affinityHost.name_label }}
</UiLink>
</template>
<template v-else #value>{{ t('none') }}</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('protect-from-accidental-deletion')">
<template #value>
<VtsStatus :status="vm.blocked_operations?.destroy === 'true'" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('protect-from-accidental-shutdown')">
<template #value>
<VtsStatus :status="isProtectedFromAccidentalShutdown" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('auto-power')">
<template #value>
<VtsStatus :status="vm.other_config.auto_poweron === 'true'" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('start-delay')" :value="formattedStartDelay" />
</VtsTabularKeyValueList>
</UiCard>
</template>
@@ -39,8 +41,9 @@
import { VM_OPERATION } from '@/libs/xen-api/xen-api.enums'
import type { XenApiVm } from '@/libs/xen-api/xen-api.types'
import { useHostStore } from '@/stores/xen-api/host.store'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'

View File

@@ -3,7 +3,9 @@
<UiTitle>
{{ t('resource-management') }}
</UiTitle>
<VtsQuickInfoRow v-for="{ label, value } of resources" :key="label" :label :value />
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow v-for="{ label, value } of resources" :key="label" :label :value />
</VtsTabularKeyValueList>
</UiCard>
</template>
@@ -11,7 +13,8 @@
import type { XenApiVm } from '@/libs/xen-api/xen-api.types'
import { useVmGuestMetricsStore } from '@/stores/xen-api/vm-guest-metrics.store'
import { useVmMetricsStore } from '@/stores/xen-api/vm-metrics.store'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { formatSizeRaw } from '@core/utils/size.util'

View File

@@ -3,14 +3,17 @@
<UiTitle>
{{ t('storage-configuration') }}
</UiTitle>
<VtsQuickInfoRow :label="t('suspend-storage-repository')" :value="srRepo?.uuid ?? t('none')" />
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('suspend-storage-repository')" :value="srRepo?.uuid ?? t('none')" />
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import type { XenApiVm } from '@/libs/xen-api/xen-api.types'
import { useSrStore } from '@/stores/xen-api/sr.store'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { computed } from 'vue'

View File

@@ -3,13 +3,16 @@
<UiTitle>
{{ t('networking') }}
</UiTitle>
<VtsQuickInfoRow :label="t('nic-type')" :value="vm.platform.nic_type" />
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('nic-type')" :value="vm.platform.nic_type" />
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import type { XenApiVm } from '@/libs/xen-api/xen-api.types'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { useI18n } from 'vue-i18n'

View File

@@ -3,31 +3,33 @@
<UiTitle>
{{ t('virtualization-boot-settings') }}
</UiTitle>
<VtsQuickInfoRow :label="t('virtualization-mode')" :value="virtualizationMode" />
<VtsQuickInfoRow :label="t('secure-boot')">
<template #value>
<VtsStatus :status="vm.platform.secureboot === 'true'" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow
:label="t('virtual-tpm')"
:value="vm.VTPMs.length > 0 ? (vtpm?.uuid ?? t('unknown')) : t('none')"
/>
<VtsQuickInfoRow :label="t('viridian')">
<template #value>
<VtsStatus :status="vm.platform.viridian === 'true'" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('manage-citrix-pv-drivers-via-windows-update')">
<template #value>
<VtsStatus :status="vm.has_vendor_device" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('nested-virtualization')">
<template #value>
<VtsStatus :status="isNestedVirtualizationEnabled" />
</template>
</VtsQuickInfoRow>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('virtualization-mode')" :value="virtualizationMode" />
<VtsTabularKeyValueRow :label="t('secure-boot')">
<template #value>
<VtsStatus :status="vm.platform.secureboot === 'true'" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow
:label="t('virtual-tpm')"
:value="vm.VTPMs.length > 0 ? (vtpm?.uuid ?? t('unknown')) : t('none')"
/>
<VtsTabularKeyValueRow :label="t('viridian')">
<template #value>
<VtsStatus :status="vm.platform.viridian === 'true'" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('manage-citrix-pv-drivers-via-windows-update')">
<template #value>
<VtsStatus :status="vm.has_vendor_device" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('nested-virtualization')">
<template #value>
<VtsStatus :status="isNestedVirtualizationEnabled" />
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</UiCard>
</template>
@@ -36,8 +38,9 @@ import type { XenApiVm } from '@/libs/xen-api/xen-api.types'
import { useHostStore } from '@/stores/xen-api/host.store'
import { usePoolStore } from '@/stores/xen-api/pool.store'
import { useVtpmStore } from '@/stores/xen-api/vtpm.store.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { satisfies } from 'semver'

View File

@@ -2,7 +2,7 @@
<VtsStateHero v-if="host === undefined" format="page" type="not-found" size="large">
{{ t('object-not-found', { id }) }}
</VtsStateHero>
<VtsColumns v-else>
<VtsColumns v-else extra-space-around>
<VtsColumn>
<HostSystemGeneralInformation :host />
<HostSystemNetworking :host />

View File

@@ -3,7 +3,7 @@
<VtsStateHero v-else-if="pool === undefined" format="page" type="no-data" size="medium">
{{ t('no-data') }}
</VtsStateHero>
<VtsColumns v-else>
<VtsColumns v-else extra-space-around>
<VtsColumn>
<PoolGeneralInfo :pool />
<PoolNetworking :pool />

View File

@@ -3,77 +3,77 @@
<UiCard class="settings-page">
<UiTitle>{{ t('about') }}</UiTitle>
<VtsColumns class="about-columns">
<VtsQuickInfoColumn>
<VtsTabularKeyValueList>
<div class="typo-h5">Xen Orchestra Lite</div>
<VtsQuickInfoColumn>
<VtsQuickInfoRow :label="t('version')">
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('version')">
<template #value>
{{ `v${xoLiteVersion}` }}
<code v-if="xoLiteGitHead">{{ `(${xoLiteGitHead.slice(0, 5)})` }}</code>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('news')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('news')">
<template #value>
<UiLink size="medium" href="https://xen-orchestra.com/blog/">
{{ t('news-name', { name: 'Xen Orchestra' }) }}
</UiLink>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('community')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('community')">
<template #value>
<UiLink size="medium" href="https://xcp-ng.org/forum/category/12/xen-orchestra">
{{ t('community-name', { name: 'Xen Orchestra' }) }}
</UiLink>
</template>
</VtsQuickInfoRow>
</VtsTabularKeyValueRow>
<!-- #TODO we dont have ofical documentation for xo-lite -->
<!--
<VtsQuickInfoRow :label="t('documentation')">
<VtsTabularKeyValueRow :label="t('documentation')">
<template #value>
<UiLink size="medium" href="https://github.com/vatesfr/xen-orchestra/tree/master/%40xen-orchestra/lite">
{{ t('documentation-name', { name: 'XO Lite' }) }}
</UiLink>
</template>
</VtsQuickInfoRow>
</VtsTabularKeyValueRow>
-->
</VtsQuickInfoColumn>
</VtsQuickInfoColumn>
<VtsQuickInfoColumn>
</VtsTabularKeyValueList>
</VtsTabularKeyValueList>
<VtsTabularKeyValueList>
<div class="typo-h5">XCP-ng</div>
<VtsQuickInfoColumn>
<VtsQuickInfoRow :label="t('version')">
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('version')">
<template #value>{{ `v${xcpVersion}` }}</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('news')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('news')">
<template #value>
<UiLink size="medium" href="https://xcp-ng.org/blog/">
{{ t('news-name', { name: 'XCP-ng' }) }}
</UiLink>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('community')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('community')">
<template #value>
<UiLink size="medium" href="https://xcp-ng.org/forum">
{{ t('community-name', { name: 'XCP-ng' }) }}
</UiLink>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('documentation')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('documentation')">
<template #value>
<UiLink size="medium" href="https://xcp-ng.org/docs/">
{{ t('documentation-name', { name: 'XCP-ng' }) }}
</UiLink>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('support')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('support')">
<template #value>
<UiLink size="medium" href="https://xcp-ng.com/">
{{ t('professional-support') }}
</UiLink>
</template>
</VtsQuickInfoRow>
</VtsQuickInfoColumn>
</VtsQuickInfoColumn>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</VtsTabularKeyValueList>
</VtsColumns>
<UiTitle>{{ t('appearance') }}</UiTitle>
<div class="options">
@@ -95,16 +95,18 @@
</div>
<UiTitle>{{ t('language') }}</UiTitle>
<!-- for regular spacing using VtsQuickInfoRow even label template is not used for this -->
<VtsQuickInfoRow>
<template #label>
<VtsSelect :id="localeSelectId" icon="fa:earth-americas" accent="brand" />
</template>
<template #value>
<UiLink size="medium" href="https://translate.vates.tech/engage/xen-orchestra/">
{{ t('missing-translations?') }}
</UiLink>
</template>
</VtsQuickInfoRow>
<VtsKeyValueList>
<VtsKeyValueRow>
<template #label>
<VtsSelect :id="localeSelectId" icon="fa:earth-americas" accent="brand" />
</template>
<template #value>
<UiLink size="medium" href="https://translate.vates.tech/engage/xen-orchestra/">
{{ t('missing-translations?') }}
</UiLink>
</template>
</VtsKeyValueRow>
</VtsKeyValueList>
<UiInfo accent="info">{{ t('untranslated-text-helper') }}</UiInfo>
</UiCard>
</template>
@@ -115,9 +117,11 @@ import { useHostStore } from '@/stores/xen-api/host.store.ts'
import { usePoolStore } from '@/stores/xen-api/pool.store.ts'
import VtsColumns from '@core/components/columns/VtsColumns.vue'
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import VtsQuickInfoColumn from '@core/components/quick-info-column/VtsQuickInfoColumn.vue'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsKeyValueList from '@core/components/key-value-list/VtsKeyValueList.vue'
import VtsKeyValueRow from '@core/components/key-value-row/VtsKeyValueRow.vue'
import VtsSelect from '@core/components/select/VtsSelect.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiHeadBar from '@core/components/ui/head-bar/UiHeadBar.vue'
import UiInfo from '@core/components/ui/info/UiInfo.vue'

View File

@@ -2,7 +2,7 @@
<VtsStateHero v-if="vm === undefined" format="page" type="not-found" size="large">
{{ t('object-not-found', { id }) }}
</VtsStateHero>
<VtsColumns v-else>
<VtsColumns v-else extra-space-around>
<VtsColumn>
<VmGeneralInfo :vm />
<VmSystemNetworking :vm />

View File

@@ -49,3 +49,16 @@
</VtsColumn>
</VtsColumns>
```
## With extra space around
```vue-template
<VtsColumns extra-space-around>
<VtsColumn class="column">
<div>1st column</div>
</VtsColumn>
<VtsColumn class="column">
<div>2nd column</div>
</VtsColumn>
</VtsColumns>
```

View File

@@ -3,6 +3,7 @@
v-slot="{ properties }"
:params="[
prop('columns').num().default(2).widget(),
prop('extra-space-around').bool().widget(),
slot().help('Meant to receive VtsColumn component or any element'),
]"
:presets

View File

@@ -0,0 +1,17 @@
<template>
<ComponentStory :params="[slot().help('Meant to receive VtsKeyValueRow components')]">
<VtsKeyValueList>
<VtsKeyValueRow label="Operating System" value="XenServer 8.3" />
<VtsKeyValueRow label="CPUs" value="4 vCPUs" />
<VtsKeyValueRow label="RAM" value="8 GiB" />
<VtsKeyValueRow label="IP Address" value="192.168.1.10" />
</VtsKeyValueList>
</ComponentStory>
</template>
<script lang="ts" setup>
import ComponentStory from '@/components/component-story/ComponentStory.vue'
import { slot } from '@/libs/story/story-param'
import VtsKeyValueList from '@core/components/key-value-list/VtsKeyValueList.vue'
import VtsKeyValueRow from '@core/components/key-value-row/VtsKeyValueRow.vue'
</script>

View File

@@ -0,0 +1,28 @@
<template>
<ComponentStory
v-slot="{ properties }"
:params="[
prop('label').str().preset('CPU').widget(),
prop('value').str().preset('4 vCPUs').widget(),
slot('label').help('Overrides the label prop'),
slot('value').help('Overrides the value prop, meant to receive text or inline elements'),
]"
>
<dl class="pair-wrapper">
<VtsKeyValuePair v-bind="properties" />
</dl>
</ComponentStory>
</template>
<script lang="ts" setup>
import ComponentStory from '@/components/component-story/ComponentStory.vue'
import { prop, slot } from '@/libs/story/story-param'
import VtsKeyValuePair from '@core/components/key-value-pair/VtsKeyValuePair.vue'
</script>
<style lang="postcss" scoped>
.pair-wrapper {
display: flex;
gap: 2.4rem;
}
</style>

View File

@@ -0,0 +1,22 @@
<template>
<ComponentStory
v-slot="{ properties }"
:params="[
prop('label').str().preset('IP Address').widget(),
prop('value').str().preset('192.168.1.10').widget(),
slot('label').help('Overrides the label prop'),
slot('value').help('Overrides the value prop, meant to receive text or inline elements'),
]"
>
<VtsKeyValueList>
<VtsKeyValueRow v-bind="properties" />
</VtsKeyValueList>
</ComponentStory>
</template>
<script lang="ts" setup>
import ComponentStory from '@/components/component-story/ComponentStory.vue'
import { prop, slot } from '@/libs/story/story-param'
import VtsKeyValueList from '@core/components/key-value-list/VtsKeyValueList.vue'
import VtsKeyValueRow from '@core/components/key-value-row/VtsKeyValueRow.vue'
</script>

View File

@@ -0,0 +1,20 @@
<template>
<ComponentStory
v-slot="{ properties }"
:params="[prop('fullHeight').bool().widget(), slot().help('Meant to receive VtsTabularKeyValueRow components')]"
>
<VtsTabularKeyValueList v-bind="properties">
<VtsTabularKeyValueRow label="Operating System" value="XenServer 8.3" />
<VtsTabularKeyValueRow label="CPUs" value="4 vCPUs" />
<VtsTabularKeyValueRow label="RAM" value="8 GiB" />
<VtsTabularKeyValueRow label="IP Address" value="192.168.1.10" />
</VtsTabularKeyValueList>
</ComponentStory>
</template>
<script lang="ts" setup>
import ComponentStory from '@/components/component-story/ComponentStory.vue'
import { prop, slot } from '@/libs/story/story-param'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
</script>

View File

@@ -0,0 +1,22 @@
<template>
<ComponentStory
v-slot="{ properties }"
:params="[
prop('label').str().preset('IP Address').widget(),
prop('value').str().preset('192.168.1.10').widget(),
slot('label').help('Overrides the label prop'),
slot('value').help('Overrides the value prop, meant to receive text or inline elements'),
]"
>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow v-bind="properties" />
</VtsTabularKeyValueList>
</ComponentStory>
</template>
<script lang="ts" setup>
import ComponentStory from '@/components/component-story/ComponentStory.vue'
import { prop, slot } from '@/libs/story/story-param'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
</script>

View File

@@ -60,6 +60,9 @@ declare module 'vue-router/auto-routes' {
'/story/web-core/donut-chart-with-legend/vts-donut-chart-with-legend': RouteRecordInfo<'/story/web-core/donut-chart-with-legend/vts-donut-chart-with-legend', '/story/web-core/donut-chart-with-legend/vts-donut-chart-with-legend', Record<never, never>, Record<never, never>>,
'/story/web-core/dropdown-title/vts-dropdown-title': RouteRecordInfo<'/story/web-core/dropdown-title/vts-dropdown-title', '/story/web-core/dropdown-title/vts-dropdown-title', Record<never, never>, Record<never, never>>,
'/story/web-core/input-wrapper/vts-input-wrapper': RouteRecordInfo<'/story/web-core/input-wrapper/vts-input-wrapper', '/story/web-core/input-wrapper/vts-input-wrapper', Record<never, never>, Record<never, never>>,
'/story/web-core/key-value-list/vts-key-value-list': RouteRecordInfo<'/story/web-core/key-value-list/vts-key-value-list', '/story/web-core/key-value-list/vts-key-value-list', Record<never, never>, Record<never, never>>,
'/story/web-core/key-value-pair/vts-key-value-pair': RouteRecordInfo<'/story/web-core/key-value-pair/vts-key-value-pair', '/story/web-core/key-value-pair/vts-key-value-pair', Record<never, never>, Record<never, never>>,
'/story/web-core/key-value-row/vts-key-value-row': RouteRecordInfo<'/story/web-core/key-value-row/vts-key-value-row', '/story/web-core/key-value-row/vts-key-value-row', Record<never, never>, Record<never, never>>,
'/story/web-core/legend-group/vts-legend-group': RouteRecordInfo<'/story/web-core/legend-group/vts-legend-group', '/story/web-core/legend-group/vts-legend-group', Record<never, never>, Record<never, never>>,
'/story/web-core/object-icon/vts-object-icon': RouteRecordInfo<'/story/web-core/object-icon/vts-object-icon', '/story/web-core/object-icon/vts-object-icon', Record<never, never>, Record<never, never>>,
'/story/web-core/resources/vts-resource': RouteRecordInfo<'/story/web-core/resources/vts-resource', '/story/web-core/resources/vts-resource', Record<never, never>, Record<never, never>>,
@@ -71,6 +74,8 @@ declare module 'vue-router/auto-routes' {
'/story/web-core/tab/router-tab': RouteRecordInfo<'/story/web-core/tab/router-tab', '/story/web-core/tab/router-tab', Record<never, never>, Record<never, never>>,
'/story/web-core/tab/tab-item': RouteRecordInfo<'/story/web-core/tab/tab-item', '/story/web-core/tab/tab-item', Record<never, never>, Record<never, never>>,
'/story/web-core/tab/tab-list': RouteRecordInfo<'/story/web-core/tab/tab-list', '/story/web-core/tab/tab-list', Record<never, never>, Record<never, never>>,
'/story/web-core/tabular-key-value-list/vts-tabular-key-value-list': RouteRecordInfo<'/story/web-core/tabular-key-value-list/vts-tabular-key-value-list', '/story/web-core/tabular-key-value-list/vts-tabular-key-value-list', Record<never, never>, Record<never, never>>,
'/story/web-core/tabular-key-value-row/vts-tabular-key-value-row': RouteRecordInfo<'/story/web-core/tabular-key-value-row/vts-tabular-key-value-row', '/story/web-core/tabular-key-value-row/vts-tabular-key-value-row', Record<never, never>, Record<never, never>>,
'/story/web-core/tree/vts-tree-item': RouteRecordInfo<'/story/web-core/tree/vts-tree-item', '/story/web-core/tree/vts-tree-item', Record<never, never>, Record<never, never>>,
'/story/web-core/tree/vts-tree-item-error': RouteRecordInfo<'/story/web-core/tree/vts-tree-item-error', '/story/web-core/tree/vts-tree-item-error', Record<never, never>, Record<never, never>>,
'/story/web-core/tree/vts-tree-list': RouteRecordInfo<'/story/web-core/tree/vts-tree-list', '/story/web-core/tree/vts-tree-list', Record<never, never>, Record<never, never>>,

View File

@@ -25,7 +25,10 @@ h5,
h6,
p,
ol,
ul {
ul,
dl,
dt,
dd {
margin: 0;
padding: 0;
font-weight: inherit;
@@ -36,6 +39,10 @@ ul {
list-style: none;
}
dd {
margin-inline-start: 0;
}
img {
max-width: 100%;
height: auto;

View File

@@ -13,9 +13,13 @@ defineSlots<{
<style lang="postcss" scoped>
.vts-column {
flex: 1;
flex-basis: 0;
display: flex;
flex-direction: column;
gap: 0.8rem;
min-width: 0;
@container vts-columns (max-width: 90rem) {
flex-basis: 100%;
}
}
</style>

View File

@@ -1,16 +1,16 @@
<template>
<div class="vts-columns" :class="{ mobile: uiStore.isSmall }">
<div class="vts-columns" :class="{ 'extra-space-around': extraSpaceAround }">
<component :is="nodes[index - 1] ?? VtsColumn" v-for="index of columns" :key="index" />
</div>
</template>
<script lang="ts" setup>
import VtsColumn from '@core/components/column/VtsColumn.vue'
import { useUiStore } from '@core/stores/ui.store.ts'
import { computed } from 'vue'
const { columns: _columns = 2 } = defineProps<{
columns?: number
extraSpaceAround?: boolean
}>()
const slots = defineSlots<{
@@ -20,19 +20,28 @@ const slots = defineSlots<{
const nodes = computed(() => slots.default())
const columns = computed(() => Math.max(_columns, nodes.value.length))
const uiStore = useUiStore()
</script>
<style lang="postcss" scoped>
.vts-columns {
container-type: inline-size;
container-name: vts-columns;
display: flex;
flex-wrap: wrap;
gap: 0.8rem;
padding: 0.8rem;
flex-direction: row;
&.mobile {
flex-direction: column;
&.extra-space-around {
margin: 0.8rem;
}
& > * {
flex: 1 0 0;
}
@container vts-columns (max-width: 60rem) {
& > * {
flex-basis: 100%;
}
}
}
</style>

View File

@@ -1,11 +1,11 @@
<template>
<div class="vts-quick-info-column">
<dl class="vts-key-value-list">
<slot />
</div>
</dl>
</template>
<style lang="postcss" scoped>
.vts-quick-info-column {
.vts-key-value-list {
display: flex;
flex-direction: column;
gap: 1.6rem;

View File

@@ -0,0 +1,48 @@
<template>
<dt class="typo-body-regular label">
<slot name="label">
{{ label }}
</slot>
</dt>
<dd class="typo-body-regular value">
<span v-tooltip class="text-ellipsis">
<slot name="value">
{{ value }}
</slot>
</span>
</dd>
</template>
<script lang="ts" setup>
import { vTooltip } from '@core/directives/tooltip.directive'
defineProps<{
label?: string
value?: string
}>()
defineSlots<{
label?(): any
value?(): any
}>()
</script>
<style lang="postcss" scoped>
.label {
color: var(--color-neutral-txt-secondary);
}
.value {
color: var(--color-neutral-txt-primary);
display: flex;
align-items: center;
gap: 0.8rem;
min-width: 0;
.text-ellipsis {
&:empty::before {
content: '-';
}
}
}
</style>

View File

@@ -0,0 +1,45 @@
<template>
<div class="vts-key-value-row" :class="{ mobile: uiStore.isSmallOrMedium }">
<VtsKeyValuePair :label :value>
<template v-if="slots.label" #label>
<slot name="label" />
</template>
<template v-if="slots.value" #value>
<slot name="value" />
</template>
</VtsKeyValuePair>
</div>
</template>
<script lang="ts" setup>
import VtsKeyValuePair from '@core/components/key-value-pair/VtsKeyValuePair.vue'
import { useUiStore } from '@core/stores/ui.store.ts'
defineProps<{
label?: string
value?: string
}>()
const slots = defineSlots<{
label?(): any
value?(): any
}>()
const uiStore = useUiStore()
</script>
<style lang="postcss" scoped>
.vts-key-value-row {
display: flex;
gap: 2.4rem;
&.mobile {
flex-direction: column;
gap: 0.8rem;
}
:deep(dt) {
flex-shrink: 0;
}
}
</style>

View File

@@ -1,59 +0,0 @@
<template>
<div class="vts-quick-info-row" :class="{ mobile: uiStore.isSmall }">
<span v-tooltip class="typo-body-regular label text-ellipsis">
<slot name="label">
{{ label }}
</slot>
</span>
<span v-tooltip class="typo-body-regular value text-ellipsis">
<slot name="value">
{{ value }}
</slot>
</span>
</div>
</template>
<script lang="ts" setup>
import { vTooltip } from '@core/directives/tooltip.directive'
import { useUiStore } from '@core/stores/ui.store.ts'
defineProps<{
label?: string
value?: string
}>()
defineSlots<{
label?(): any
value?(): any
}>()
const uiStore = useUiStore()
</script>
<style lang="postcss" scoped>
.vts-quick-info-row {
display: flex;
gap: 2.4rem;
&.mobile {
flex-direction: column;
gap: 0.8rem;
}
.label {
flex-shrink: 0;
color: var(--color-neutral-txt-secondary);
}
.value {
color: var(--color-neutral-txt-primary);
display: flex;
align-items: center;
gap: 0.8rem;
&:empty::before {
content: '-';
}
}
}
</style>

View File

@@ -0,0 +1,29 @@
<template>
<dl class="vts-tabular-key-value-list" :class="{ 'full-height': fullHeight }">
<slot />
</dl>
</template>
<script lang="ts" setup>
defineProps<{
fullHeight?: boolean
}>()
</script>
<style lang="postcss" scoped>
.vts-tabular-key-value-list {
container-type: inline-size;
container-name: vts-tabular-key-value-list;
display: grid;
grid-template-columns: minmax(min-content, 20rem) 1fr;
row-gap: 1.6rem;
column-gap: 2.4rem;
align-items: start;
align-self: flex-start;
width: 100%;
&.full-height {
height: 100%;
}
}
</style>

View File

@@ -0,0 +1,42 @@
<template>
<div class="vts-tabular-key-value-row">
<VtsKeyValuePair :label :value>
<template v-if="slots.label" #label>
<slot name="label" />
</template>
<template v-if="slots.value" #value>
<slot name="value" />
</template>
</VtsKeyValuePair>
</div>
</template>
<script lang="ts" setup>
import VtsKeyValuePair from '@core/components/key-value-pair/VtsKeyValuePair.vue'
defineProps<{
label?: string
value?: string
}>()
const slots = defineSlots<{
label?(): any
value?(): any
}>()
</script>
<style lang="postcss" scoped>
.vts-tabular-key-value-row {
display: grid;
grid-template-columns: subgrid;
grid-column: span 2;
align-items: start;
@container vts-tabular-key-value-list (max-width: 40rem) {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 0.8rem;
}
}
</style>

View File

@@ -4,20 +4,22 @@
{{ t('configuration') }}
</UiTitle>
<template v-if="!isSmartModeEnabled">
<VtsQuickInfoRow :label="t('smart-mode')">
<template #value>
<VtsStatus status="disabled" />
</template>
</VtsQuickInfoRow>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('smart-mode')">
<template #value>
<VtsStatus status="disabled" />
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</template>
<VtsColumns v-else>
<VtsColumn class="column">
<VtsQuickInfoRow :label="t('smart-mode')">
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('smart-mode')">
<template #value>
<VtsStatus status="enabled" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('vms-tags')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('vms-tags')">
<template v-if="smartModeTags?.included !== undefined && smartModeTags.included.length > 0" #value>
<UiTagsList>
<UiTag v-for="tag in smartModeTags.included" :key="tag" accent="info" variant="secondary">
@@ -25,10 +27,10 @@
</UiTag>
</UiTagsList>
</template>
</VtsQuickInfoRow>
</VtsColumn>
<VtsColumn class="column">
<VtsQuickInfoRow :label="t('resident-on')">
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('resident-on')">
<template v-if="smartModePools !== undefined" #value>
<UiLink
v-for="pool in smartModePools.included"
@@ -40,8 +42,8 @@
{{ pool.name_label }}
</UiLink>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('excluded-vms-tags')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('excluded-vms-tags')">
<template v-if="smartModeTags !== undefined && smartModeTags.excluded.length > 0" #value>
<UiTagsList>
<UiTag v-for="tag in smartModeTags.excluded" :key="tag" accent="info" variant="secondary">
@@ -49,10 +51,10 @@
</UiTag>
</UiTagsList>
</template>
</VtsQuickInfoRow>
</VtsColumn>
<VtsColumn class="column">
<VtsQuickInfoRow :label="t('not-resident-on')">
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('not-resident-on')">
<template v-if="smartModePools !== undefined" #value>
<UiLink
v-for="pool in smartModePools.excluded"
@@ -64,14 +66,14 @@
{{ pool.name_label }}
</UiLink>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('power-state')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('power-state')">
<template v-if="smartModePowerState !== undefined" #value>
<VtsIcon size="small" :name="`object:vm:${toLower(smartModePowerState)}`" />
{{ smartModePowerState }}
</template>
</VtsQuickInfoRow>
</VtsColumn>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</VtsColumns>
</UiCard>
</template>
@@ -79,11 +81,11 @@
<script lang="ts" setup>
import { useXoBackedUpVmsUtils } from '@/modules/backup/composables/xo-backed-up-vms-utils.composable.ts'
import type { FrontXoVmBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import VtsColumn from '@core/components/column/VtsColumn.vue'
import VtsColumns from '@core/components/columns/VtsColumns.vue'
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiTag from '@core/components/ui/tag/UiTag.vue'
@@ -102,9 +104,3 @@ const { isSmartModeEnabled, smartModePools, smartModeTags, smartModePowerState }
() => backupJob.vms
)
</script>
<style lang="postcss" scoped>
.column {
gap: 2.4rem;
}
</style>

View File

@@ -3,21 +3,27 @@
<UiTitle>{{ t('general-information') }}</UiTitle>
<VtsColumns>
<VtsColumn>
<VtsQuickInfoRow :label="t('name')" :value="backupJob.name" />
<VtsKeyValueList>
<VtsKeyValueRow :label="t('name')" :value="backupJob.name" />
</VtsKeyValueList>
</VtsColumn>
<VtsColumn>
<VtsQuickInfoRow :label="t('id')" :value="backupJob.id" />
<VtsKeyValueList>
<VtsKeyValueRow :label="t('id')" :value="backupJob.id" />
</VtsKeyValueList>
</VtsColumn>
<VtsColumn>
<VtsQuickInfoRow :label="t('modes')">
<template v-if="modeLabels.length > 0" #value>
<UiTagsList>
<UiTag v-for="label in modeLabels" :key="label" variant="secondary" accent="info">
{{ label }}
</UiTag>
</UiTagsList>
</template>
</VtsQuickInfoRow>
<VtsKeyValueList>
<VtsKeyValueRow :label="t('modes')">
<template v-if="modeLabels.length > 0" #value>
<UiTagsList>
<UiTag v-for="label in modeLabels" :key="label" variant="secondary" accent="info">
{{ label }}
</UiTag>
</UiTagsList>
</template>
</VtsKeyValueRow>
</VtsKeyValueList>
</VtsColumn>
</VtsColumns>
</UiCard>
@@ -28,7 +34,8 @@ import { useXoBackupUtils } from '@/modules/backup/composables/xo-backup-utils.c
import type { FrontXoVmBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import VtsColumn from '@core/components/column/VtsColumn.vue'
import VtsColumns from '@core/components/columns/VtsColumns.vue'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsKeyValueList from '@core/components/key-value-list/VtsKeyValueList.vue'
import VtsKeyValueRow from '@core/components/key-value-row/VtsKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTag from '@core/components/ui/tag/UiTag.vue'
import UiTagsList from '@core/components/ui/tag/UiTagsList.vue'

View File

@@ -2,28 +2,28 @@
<UiCard>
<UiTitle>{{ t('settings') }}</UiTitle>
<VtsColumns>
<VtsColumn>
<VtsQuickInfoRow :label="t('proxy')" :value="proxy?.name" />
<VtsQuickInfoRow :label="t('snapshot-mode')">
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('proxy')" :value="proxy?.name" />
<VtsTabularKeyValueRow :label="t('snapshot-mode')">
<template v-if="backupJob.mode" #value>
<UiTag variant="secondary" accent="info">{{ snapshotModeTranslation }}</UiTag>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow
:label="t('vm-backup-failure-number-of-retries')"
:value="
settings.nRetriesVmBackupFailures !== undefined ? String(settings.nRetriesVmBackupFailures) : undefined
"
/>
<VtsQuickInfoRow :label="t('timeout')" :value="formattedTimeout" />
</VtsColumn>
<VtsColumn>
<VtsQuickInfoRow
<VtsTabularKeyValueRow :label="t('timeout')" :value="formattedTimeout" />
</VtsTabularKeyValueList>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow
:label="t('speed-limit')"
:value="maxExportRate ? `${maxExportRate.value} ${maxExportRate.prefix}` : undefined"
/>
<VtsQuickInfoRow :label="t('report-when')" :value="reportWhenValueTranslation" />
<VtsQuickInfoRow :label="t('report-recipients')">
<VtsTabularKeyValueRow :label="t('report-when')" :value="reportWhenValueTranslation" />
<VtsTabularKeyValueRow :label="t('report-recipients')">
<template #value>
<UiTagsList v-if="settings.reportRecipients">
<UiTag
@@ -36,30 +36,30 @@
</UiTag>
</UiTagsList>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow
:label="t('concurrency')"
:value="settings.concurrency !== undefined ? String(settings.concurrency) : undefined"
/>
</VtsColumn>
<VtsColumn>
<VtsQuickInfoRow :label="t('compression')" :value="compression" />
<VtsQuickInfoRow :label="t('offline-backup')">
</VtsTabularKeyValueList>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('compression')" :value="compression" />
<VtsTabularKeyValueRow :label="t('offline-backup')">
<template #value>
<VtsEnabledState :enabled="!!settings.offlineBackup" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('shorter-backup-reports')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('shorter-backup-reports')">
<template #value>
<VtsEnabledState :enabled="settings.backupReportTpl ? settings.backupReportTpl === 'compactMjml' : false" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('merge-backups-synchronously')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('merge-backups-synchronously')">
<template #value>
<VtsEnabledState :enabled="!!settings.mergeBackupsSynchronously" />
</template>
</VtsQuickInfoRow>
</VtsColumn>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</VtsColumns>
</UiCard>
</template>
@@ -67,10 +67,10 @@
<script setup lang="ts">
import { useXoBackupJobSettingsUtils } from '@/modules/backup/composables/backup-job-settings/xo-backup-job-settings.composable.ts'
import type { FrontXoVmBackupJob } from '@/modules/backup/remote-resources/use-xo-backup-job-collection.ts'
import VtsColumn from '@core/components/column/VtsColumn.vue'
import VtsColumns from '@core/components/columns/VtsColumns.vue'
import VtsEnabledState from '@core/components/enabled-state/VtsEnabledState.vue'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTag from '@core/components/ui/tag/UiTag.vue'
import UiTagsList from '@core/components/ui/tag/UiTagsList.vue'

View File

@@ -1,20 +1,20 @@
<template>
<VtsQuickInfoCard class="host-dashboard-quick-info" :loading="!areHostsReady">
<VtsQuickInfoColumn>
<VtsQuickInfoRow :label="t('state')">
<VtsKeyValueList>
<VtsKeyValueRow :label="t('state')">
<template #value>
<span class="power-state">
<VtsIcon :name="powerState.icon" size="medium" />
{{ powerState.text }}
</span>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('ip-address')" :value="host.address" />
<VtsQuickInfoRow
</VtsKeyValueRow>
<VtsKeyValueRow :label="t('ip-address')" :value="host.address" />
<VtsKeyValueRow
:label="t('started')"
:value="host.power_state === HOST_POWER_STATE.RUNNING ? relativeStartTime : undefined"
/>
<VtsQuickInfoRow :label="t('master')">
<VtsKeyValueRow :label="t('master')">
<template #value>
<template v-if="isMaster">
<VtsIcon v-tooltip="t('master')" name="status:primary-circle" size="medium" />
@@ -29,28 +29,28 @@
{{ masterHost.name_label }}
</UiLink>
</template>
</VtsQuickInfoRow>
</VtsQuickInfoColumn>
<VtsQuickInfoColumn>
<VtsQuickInfoRow :label="t('uuid')" :value="host.id" />
<VtsQuickInfoRow :label="t('description')" :value="host.name_description" />
<VtsQuickInfoRow :label="t('version')" :value="host.version" />
<VtsQuickInfoRow
</VtsKeyValueRow>
</VtsKeyValueList>
<VtsKeyValueList>
<VtsKeyValueRow :label="t('uuid')" :value="host.id" />
<VtsKeyValueRow :label="t('description')" :value="host.name_description" />
<VtsKeyValueRow :label="t('version')" :value="host.version" />
<VtsKeyValueRow
:label="t('hardware')"
:value="`${host.bios_strings['system-manufacturer']} (${host.bios_strings['system-product-name']})`"
/>
</VtsQuickInfoColumn>
<VtsQuickInfoColumn>
<VtsQuickInfoRow :label="t('cores-with-sockets')" :value="`${host.cpus.cores} (${host.cpus.sockets})`" />
<VtsQuickInfoRow :label="t('ram')" :value="`${ram.value} ${ram.prefix}`" />
<VtsQuickInfoRow :label="t('tags')">
</VtsKeyValueList>
<VtsKeyValueList>
<VtsKeyValueRow :label="t('cores-with-sockets')" :value="`${host.cpus.cores} (${host.cpus.sockets})`" />
<VtsKeyValueRow :label="t('ram')" :value="`${ram.value} ${ram.prefix}`" />
<VtsKeyValueRow :label="t('tags')">
<template #value>
<UiTagsList v-if="host.tags.length">
<UiTag v-for="tag in host.tags" :key="tag" accent="info" variant="secondary">{{ tag }}</UiTag>
</UiTagsList>
</template>
</VtsQuickInfoRow>
</VtsQuickInfoColumn>
</VtsKeyValueRow>
</VtsKeyValueList>
</VtsQuickInfoCard>
</template>
@@ -58,9 +58,9 @@
import { useXoHostUtils } from '@/modules/host/composables/xo-host-utils.composable.ts'
import { useXoHostCollection, type FrontXoHost } from '@/modules/host/remote-resources/use-xo-host-collection.ts'
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import VtsKeyValueList from '@core/components/key-value-list/VtsKeyValueList.vue'
import VtsKeyValueRow from '@core/components/key-value-row/VtsKeyValueRow.vue'
import VtsQuickInfoCard from '@core/components/quick-info-card/VtsQuickInfoCard.vue'
import VtsQuickInfoColumn from '@core/components/quick-info-column/VtsQuickInfoColumn.vue'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiTag from '@core/components/ui/tag/UiTag.vue'
import UiTagsList from '@core/components/ui/tag/UiTagsList.vue'

View File

@@ -3,56 +3,58 @@
<UiTitle>
{{ t('general-information') }}
</UiTitle>
<VtsQuickInfoRow :label="t('name')" :value="host.name_label" />
<VtsQuickInfoRow :label="t('uuid')" :value="host.id" />
<VtsQuickInfoRow :label="t('description')" :value="host.name_description" />
<VtsQuickInfoRow :label="t('tags')">
<template v-if="host.tags.length > 0" #value>
<UiTagsList>
<UiTag v-for="tag in host.tags" :key="tag" accent="info" variant="secondary">
{{ tag }}
</UiTag>
</UiTagsList>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('status')">
<template #value>
<VtsStatus :status="host.enabled" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('pool')">
<template v-if="pool !== undefined" #value>
<UiLink size="medium" :to="{ name: '/pool/[id]/dashboard', params: { id: pool.id } }" icon="object:pool">
{{ pool.name_label }}
</UiLink>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('master')">
<template #value>
<template v-if="isMaster">
<VtsIcon v-tooltip="t('master')" name="status:primary-circle" size="medium" />
{{ t('this-host') }}
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('name')" :value="host.name_label" />
<VtsTabularKeyValueRow :label="t('uuid')" :value="host.id" />
<VtsTabularKeyValueRow :label="t('description')" :value="host.name_description" />
<VtsTabularKeyValueRow :label="t('tags')">
<template v-if="host.tags.length > 0" #value>
<UiTagsList>
<UiTag v-for="tag in host.tags" :key="tag" accent="info" variant="secondary">
{{ tag }}
</UiTag>
</UiTagsList>
</template>
<UiLink
v-else-if="masterHost !== undefined"
size="medium"
:to="{ name: '/host/[id]/dashboard', params: { id: masterHost.id } }"
:icon="`object:host:${toLower(masterHost.power_state)}`"
>
{{ masterHost.name_label }}
</UiLink>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('started')">
<template v-if="host.power_state === HOST_POWER_STATE.RUNNING && host.startTime" #value>
<VtsRelativeTime :date="host.startTime * 1000" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('power-on-mode')">
<template #value>
<VtsStatus :status="host.powerOnMode !== ''" />
</template>
</VtsQuickInfoRow>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('status')">
<template #value>
<VtsStatus :status="host.enabled" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('pool')">
<template v-if="pool !== undefined" #value>
<UiLink size="medium" :to="{ name: '/pool/[id]/dashboard', params: { id: pool.id } }" icon="object:pool">
{{ pool.name_label }}
</UiLink>
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('master')">
<template #value>
<template v-if="isMaster">
<VtsIcon v-tooltip="t('master')" name="status:primary-circle" size="medium" />
{{ t('this-host') }}
</template>
<UiLink
v-else-if="masterHost !== undefined"
size="medium"
:to="{ name: '/host/[id]/dashboard', params: { id: masterHost.id } }"
:icon="`object:host:${toLower(masterHost.power_state)}`"
>
{{ masterHost.name_label }}
</UiLink>
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('started')">
<template v-if="host.power_state === HOST_POWER_STATE.RUNNING && host.startTime" #value>
<VtsRelativeTime :date="host.startTime * 1000" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('power-on-mode')">
<template #value>
<VtsStatus :status="host.powerOnMode !== ''" />
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</UiCard>
</template>
@@ -60,9 +62,10 @@
import { useXoHostCollection, type FrontXoHost } from '@/modules/host/remote-resources/use-xo-host-collection.ts'
import { useXoPoolCollection } from '@/modules/pool/remote-resources/use-xo-pool-collection.ts'
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsRelativeTime from '@core/components/relative-time/VtsRelativeTime.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiTag from '@core/components/ui/tag/UiTag.vue'

View File

@@ -3,26 +3,28 @@
<UiTitle>
{{ t('hardware-specifications') }}
</UiTitle>
<VtsQuickInfoRow
:label="t('manufacturer-info')"
:value="`${host.bios_strings['system-manufacturer']} (${host.bios_strings['system-product-name']})`"
/>
<VtsQuickInfoRow
:label="t('bios-info')"
:value="`${host.bios_strings['bios-vendor']} (${host.bios_strings['bios-version']})`"
/>
<VtsQuickInfoRow :label="t('cpu-model')" :value="host.CPUs.modelname" />
<VtsQuickInfoRow :label="t('core-socket')" :value="`${host.cpus.cores} (${host.cpus.sockets})`" />
<VtsQuickInfoRow :label="t('gpus')">
<template v-if="isReady" #value>
<template v-if="devicesNames">
{{ devicesNames }}
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow
:label="t('manufacturer-info')"
:value="`${host.bios_strings['system-manufacturer']} (${host.bios_strings['system-product-name']})`"
/>
<VtsTabularKeyValueRow
:label="t('bios-info')"
:value="`${host.bios_strings['bios-vendor']} (${host.bios_strings['bios-version']})`"
/>
<VtsTabularKeyValueRow :label="t('cpu-model')" :value="host.CPUs.modelname" />
<VtsTabularKeyValueRow :label="t('core-socket')" :value="`${host.cpus.cores} (${host.cpus.sockets})`" />
<VtsTabularKeyValueRow :label="t('gpus')">
<template v-if="isReady" #value>
<template v-if="devicesNames">
{{ devicesNames }}
</template>
<template v-else>
{{ t('none') }}
</template>
</template>
<template v-else>
{{ t('none') }}
</template>
</template>
</VtsQuickInfoRow>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</UiCard>
</template>
@@ -30,7 +32,8 @@
import type { FrontXoHost } from '@/modules/host/remote-resources/use-xo-host-collection.ts'
import { useXoPciCollection } from '@/modules/pci/remote-resources/use-xo-pci-collection.ts'
import { useXoPgpuCollection } from '@/modules/pgpu/remote-resources/use-xo-pgpu-collection.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { logicAnd } from '@vueuse/math'

View File

@@ -3,21 +3,24 @@
<UiTitle>
{{ t('networking') }}
</UiTitle>
<VtsQuickInfoRow :label="t('ip-address')" :value="host.address" />
<VtsQuickInfoRow :label="t('remote-syslog')" :value="host.logging.syslog_destination" />
<VtsQuickInfoRow :label="t('iscsi-iqn')" :value="host.iscsiIqn" />
<VtsQuickInfoRow :label="t('multi-pathing')">
<template #value>
<VtsStatus :status="host.multipathing" />
</template>
</VtsQuickInfoRow>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('ip-address')" :value="host.address" />
<VtsTabularKeyValueRow :label="t('remote-syslog')" :value="host.logging.syslog_destination" />
<VtsTabularKeyValueRow :label="t('iscsi-iqn')" :value="host.iscsiIqn" />
<VtsTabularKeyValueRow :label="t('multi-pathing')">
<template #value>
<VtsStatus :status="host.multipathing" />
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import type { FrontXoHost } from '@/modules/host/remote-resources/use-xo-host-collection.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { useI18n } from 'vue-i18n'

View File

@@ -3,14 +3,17 @@
<UiTitle>
{{ t('resource-management') }}
</UiTitle>
<VtsQuickInfoRow :label="t('control-domain-memory')" :value="controllerMemory" />
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('control-domain-memory')" :value="controllerMemory" />
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import type { FrontXoHost } from '@/modules/host/remote-resources/use-xo-host-collection.ts'
import { useXoVmControllerCollection } from '@/modules/vm/remote-resources/use-xo-vm-controller-collection.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { formatSize } from '@core/utils/size.util.ts'

View File

@@ -3,20 +3,23 @@
<UiTitle>
{{ t('software-tooling') }}
</UiTitle>
<VtsQuickInfoRow :label="t('version')" :value="host.version" />
<VtsQuickInfoRow :label="t('build-number')" :value="host.build" />
<VtsQuickInfoRow :label="t('toolstack-uptime')">
<template v-if="host.power_state === HOST_POWER_STATE.RUNNING" #value>
<VtsRelativeTime :date="Number(host.agentStartTime) * 1000" />
</template>
</VtsQuickInfoRow>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('version')" :value="host.version" />
<VtsTabularKeyValueRow :label="t('build-number')" :value="host.build" />
<VtsTabularKeyValueRow :label="t('toolstack-uptime')">
<template v-if="host.power_state === HOST_POWER_STATE.RUNNING" #value>
<VtsRelativeTime :date="Number(host.agentStartTime) * 1000" />
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import type { FrontXoHost } from '@/modules/host/remote-resources/use-xo-host-collection.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsRelativeTime from '@core/components/relative-time/VtsRelativeTime.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { HOST_POWER_STATE } from '@vates/types'

View File

@@ -4,30 +4,31 @@
{{ t('connections') }}
</UiTitle>
<VtsStateHero v-if="!areServersReady" format="card" type="busy" size="medium" />
<template v-else>
<VtsQuickInfoRow :label="t('ip-address')" :value="server?.host" />
<VtsQuickInfoRow :label="t('proxy-url')" :value="server?.httpProxy" />
<VtsQuickInfoRow :label="t('username')" :value="server?.username" />
<VtsQuickInfoRow :label="t('read-only')">
<VtsTabularKeyValueList v-else>
<VtsTabularKeyValueRow :label="t('ip-address')" :value="server?.host" />
<VtsTabularKeyValueRow :label="t('proxy-url')" :value="server?.httpProxy" />
<VtsTabularKeyValueRow :label="t('username')" :value="server?.username" />
<VtsTabularKeyValueRow :label="t('read-only')">
<template #value>
<VtsStatus :status="server?.readOnly ?? false" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('self-signed-certificates')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('self-signed-certificates')">
<template #value>
<VtsStatus :status="server?.allowUnauthorized ?? false" />
</template>
</VtsQuickInfoRow>
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import type { FrontXoPool } from '@/modules/pool/remote-resources/use-xo-pool-collection.ts'
import { useXoServerCollection } from '@/modules/server/remote-resources/use-xo-server-collection.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsStateHero from '@core/components/state-hero/VtsStateHero.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { computed } from 'vue'

View File

@@ -3,22 +3,25 @@
<UiTitle>
{{ t('general-information') }}
</UiTitle>
<VtsQuickInfoRow :label="t('name')" :value="pool.name_label" />
<VtsQuickInfoRow :label="t('uuid')" :value="pool.id" />
<VtsQuickInfoRow :label="t('description')" :value="pool.name_description" />
<VtsQuickInfoRow :label="t('tags')">
<template v-if="pool.tags.length > 0" #value>
<UiTagsList>
<UiTag v-for="tag in pool.tags" :key="tag" accent="info" variant="secondary">{{ tag }}</UiTag>
</UiTagsList>
</template>
</VtsQuickInfoRow>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('name')" :value="pool.name_label" />
<VtsTabularKeyValueRow :label="t('uuid')" :value="pool.id" />
<VtsTabularKeyValueRow :label="t('description')" :value="pool.name_description" />
<VtsTabularKeyValueRow :label="t('tags')">
<template v-if="pool.tags.length > 0" #value>
<UiTagsList>
<UiTag v-for="tag in pool.tags" :key="tag" accent="info" variant="secondary">{{ tag }}</UiTag>
</UiTagsList>
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import type { FrontXoPool } from '@/modules/pool/remote-resources/use-xo-pool-collection.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTag from '@core/components/ui/tag/UiTag.vue'
import UiTagsList from '@core/components/ui/tag/UiTagsList.vue'

View File

@@ -4,8 +4,8 @@
{{ t('pool-management') }}
</UiTitle>
<VtsStateHero v-if="!areHostsReady" format="card" type="busy" size="medium" />
<template v-else>
<VtsQuickInfoRow :label="t('master')">
<VtsTabularKeyValueList v-else>
<VtsTabularKeyValueRow :label="t('master')">
<template #value>
<UiLink
v-if="primaryHost"
@@ -19,32 +19,33 @@
{{ t('none') }}
</template>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('auto-power')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('auto-power')">
<template #value>
<VtsStatus :status="pool.auto_poweron" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('high-availability')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('high-availability')">
<template #value>
<VtsStatus :status="pool.HA_enabled" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('migration-compression')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('migration-compression')">
<template #value>
<VtsStatus :status="pool.migrationCompression ?? false" />
</template>
</VtsQuickInfoRow>
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import { useXoHostCollection } from '@/modules/host/remote-resources/use-xo-host-collection.ts'
import type { FrontXoPool } from '@/modules/pool/remote-resources/use-xo-pool-collection.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsStateHero from '@core/components/state-hero/VtsStateHero.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'

View File

@@ -4,8 +4,8 @@
{{ t('networking') }}
</UiTitle>
<VtsStateHero v-if="!areNetworksReady" format="card" type="busy" size="medium" />
<template v-else>
<VtsQuickInfoRow :label="t('backup-network')">
<VtsTabularKeyValueList v-else>
<VtsTabularKeyValueRow :label="t('backup-network')">
<template #value>
<UiLink v-if="backupNetwork !== undefined" icon="object:network" :to="backupNetworkTo" size="medium">
{{ backupNetwork.name_label }}
@@ -14,8 +14,8 @@
{{ t('none') }}
</template>
</template>
</VtsQuickInfoRow>
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</UiCard>
</template>
@@ -23,8 +23,9 @@
import { useXoNetworkCollection } from '@/modules/network/remote-resources/use-xo-network-collection.ts'
import { getPoolNetworkRoute } from '@/modules/network/utils/xo-network.util.ts'
import type { FrontXoPool } from '@/modules/pool/remote-resources/use-xo-pool-collection.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsStateHero from '@core/components/state-hero/VtsStateHero.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'

View File

@@ -4,8 +4,8 @@
{{ t('storage-configuration') }}
</UiTitle>
<VtsStateHero v-if="!areSrsReady" format="card" type="busy" size="medium" />
<template v-else>
<VtsQuickInfoRow :label="t('default-storage-repository')">
<VtsTabularKeyValueList v-else>
<VtsTabularKeyValueRow :label="t('default-storage-repository')">
<template #value>
<template v-if="defaultSr">
<VtsIcon name="object:sr" size="medium" />
@@ -15,8 +15,8 @@
{{ t('none') }}
</template>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('suspend-storage-repository')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('suspend-storage-repository')">
<template #value>
<template v-if="suspendSr">
<VtsIcon name="object:sr" size="medium" />
@@ -26,8 +26,8 @@
{{ t('none') }}
</template>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('crash-dump-storage-repository')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('crash-dump-storage-repository')">
<template #value>
<template v-if="crashDumpSr">
<VtsIcon name="object:sr" size="medium" />
@@ -37,8 +37,8 @@
{{ t('none') }}
</template>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('heartbeat-storage-repository')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('heartbeat-storage-repository')">
<template #value>
<ul v-if="haSrs.length > 0">
<li v-for="haSr in haSrs" :key="haSr.id">
@@ -50,8 +50,8 @@
{{ t('none') }}
</template>
</template>
</VtsQuickInfoRow>
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</UiCard>
</template>
@@ -59,8 +59,9 @@
import type { FrontXoPool } from '@/modules/pool/remote-resources/use-xo-pool-collection.ts'
import { useXoSrCollection } from '@/modules/storage-repository/remote-resources/use-xo-sr-collection.ts'
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsStateHero from '@core/components/state-hero/VtsStateHero.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { useI18n } from 'vue-i18n'

View File

@@ -10,28 +10,28 @@
<VtsStateHero v-else-if="isEmpty" format="card" type="no-data" size="small" horizontal>
{{ t('no-replicated-vm') }}
</VtsStateHero>
<div v-else class="replication">
<VtsQuickInfoRow :label="t('vm')">
<VtsTabularKeyValueList v-else full-height>
<VtsTabularKeyValueRow :label="t('vm')">
<template v-if="vm" #value>
<UiLink size="medium" :icon="vmPowerStateIcon" :to="{ name: '/vm/[id]/dashboard', params: { id: vm.id } }">
{{ vm.name_label }}
</UiLink>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('date')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('date')">
<template v-if="formattedDate" #value>
{{ formattedDate }}
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('storage-repository')">
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('storage-repository')">
<template v-if="storageRepository" #value>
<!-- TODO Need to implement a link of the storage repository when the dedicated page to backup repository will be implemented -->
<UiLink :icon="srStatusIcon" size="medium">
{{ storageRepository.name_label }}
</UiLink>
</template>
</VtsQuickInfoRow>
</div>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</UiCard>
</template>
@@ -40,8 +40,9 @@ import { useXoSrUtils } from '@/modules/storage-repository/composables/xo-sr-uti
import { useXoSrCollection } from '@/modules/storage-repository/remote-resources/use-xo-sr-collection.ts'
import { useXoVmCollection } from '@/modules/vm/remote-resources/use-xo-vm-collection.ts'
import type { XoVmDashboard } from '@/modules/vm/types/vm-dashboard.type.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsStateHero from '@core/components/state-hero/VtsStateHero.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiCardTitle from '@core/components/ui/card-title/UiCardTitle.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
@@ -80,11 +81,3 @@ const formattedDate = computed(() =>
const { srStatusIcon } = useXoSrUtils(() => storageRepository.value)
</script>
<style lang="postcss" scoped>
.replication {
display: flex;
flex-direction: column;
gap: 2.4rem;
}
</style>

View File

@@ -9,22 +9,23 @@
</template>
</UiCardTitle>
<div v-if="areBackupRunsReady && !isError" class="backup-head">
<div class="protection-infos">
<VtsQuickInfoRow :label="t('protection-status')">
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('protection-status')">
<template #value>
<UiInfo :accent="infoVmProtectionStatus.accent">{{ infoVmProtectionStatus.text }}</UiInfo>
</template>
</VtsQuickInfoRow>
<UiButton
accent="brand"
left-icon="status:info-circle"
size="small"
variant="tertiary"
@click="openProtectionHelpModal()"
>
{{ t('what-does-protected-mean?') }}
</UiButton>
</div>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
<UiButton
accent="brand"
left-icon="status:info-circle"
size="small"
variant="tertiary"
class="button"
@click="openProtectionHelpModal()"
>
{{ t('what-does-protected-mean?') }}
</UiButton>
</div>
<UiAlert v-if="isNotInActiveJob" accent="warning">
<span class="typo-body-bold">{{ t('no-job-vm') }}</span>
@@ -56,9 +57,10 @@
<script setup lang="ts">
import { useXoBackupJobCollection } from '@/modules/backup/remote-resources/use-xo-backup-job-collection'
import type { VmDashboardRun, VmProtectionStatus, XoVmDashboard } from '@/modules/vm/types/vm-dashboard.type'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsRow from '@core/components/table/VtsRow.vue'
import VtsTable from '@core/components/table/VtsTable.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiAlert from '@core/components/ui/alert/UiAlert.vue'
import UiButton from '@core/components/ui/button/UiButton.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
@@ -141,13 +143,10 @@ const { HeadCells, BodyCells } = useBackupRunColumns({
.backup-head {
display: flex;
flex-direction: column;
gap: 2.4rem;
gap: 0.8rem;
.protection-infos {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 0.4rem;
.button {
align-self: flex-start;
}
}
</style>

View File

@@ -1,35 +1,44 @@
<template>
<VtsQuickInfoCard class="vm-dashboard-quick-info" :loading="!areVmsReady">
<VtsQuickInfoColumn>
<VtsQuickInfoRow :label="t('state')">
<VtsKeyValueList>
<VtsKeyValueRow :label="t('state')">
<template #value>
<span class="value">
<VtsIcon :name="powerState.icon" size="medium" />
{{ powerState.text }}
</span>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('ip-address')" :value="vm.mainIpAddress" />
<VtsQuickInfoRow :label="t('created-on')" :value="installDateFormatted" />
<VtsQuickInfoRow :label="t('created-by')" :value="userLabel ?? t('unknown')" />
<VtsQuickInfoRow :label="t('started')" :value="relativeStartTime" />
</VtsQuickInfoColumn>
<VtsQuickInfoColumn>
<VtsQuickInfoRow :label="t('uuid')" :value="vm.id" />
<VtsQuickInfoRow :label="t('pool')">
</VtsKeyValueRow>
<VtsKeyValueRow :label="t('ip-address')" :value="vm.mainIpAddress" />
<VtsKeyValueRow :label="t('created-on')" :value="installDateFormatted" />
<VtsKeyValueRow :label="t('created-by')" :value="userLabel ?? t('unknown')" />
<VtsKeyValueRow :label="t('started')" :value="relativeStartTime" />
</VtsKeyValueList>
<VtsKeyValueList>
<VtsKeyValueRow :label="t('uuid')" :value="vm.id" />
<VtsKeyValueRow :label="t('pool')">
<template #value>
<UiLink v-if="pool" :to="{ name: '/pool/[id]/dashboard', params: { id: pool.id } }" size="medium" icon="object:pool">
<UiLink
v-if="pool"
:to="{ name: '/pool/[id]/dashboard', params: { id: pool.id } }"
size="medium"
icon="object:pool"
>
{{ pool.name_label }}
</UiLink>
<span v-else>
{{ t('none') }}
</span>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('host')">
</VtsKeyValueRow>
<VtsKeyValueRow :label="t('host')">
<template #value>
<template v-if="host">
<UiLink :to="{ name: '/host/[id]/dashboard', params: { id: host.id } }" size="medium" :icon="`object:host:${hostPowerState}`">
<UiLink
:to="{ name: '/host/[id]/dashboard', params: { id: host.id } }"
size="medium"
:icon="`object:host:${hostPowerState}`"
>
{{ host.name_label }}
</UiLink>
<VtsIcon v-if="isMaster" v-tooltip="t('master')" name="status:primary-circle" size="medium" />
@@ -38,13 +47,13 @@
{{ t('none') }}
</template>
</template>
</VtsQuickInfoRow>
</VtsQuickInfoColumn>
<VtsQuickInfoColumn>
<VtsQuickInfoRow :label="t('description')" :value="vm.name_description" />
<VtsQuickInfoRow :label="t('os-name')" :value="vm.os_version?.name" />
<VtsQuickInfoRow :label="t('virtualization-type')" :value="virtualizationType" />
<VtsQuickInfoRow :label="t('guest-tools')">
</VtsKeyValueRow>
</VtsKeyValueList>
<VtsKeyValueList>
<VtsKeyValueRow :label="t('description')" :value="vm.name_description" />
<VtsKeyValueRow :label="t('os-name')" :value="vm.os_version?.name" />
<VtsKeyValueRow :label="t('virtualization-type')" :value="virtualizationType" />
<VtsKeyValueRow :label="t('guest-tools')">
<template #value>
<div class="value">
<VtsIcon
@@ -61,12 +70,12 @@
</template>
</div>
</template>
</VtsQuickInfoRow>
</VtsQuickInfoColumn>
<VtsQuickInfoColumn>
<VtsQuickInfoRow :label="t('vcpus')" :value="String(vm.CPUs.number)" />
<VtsQuickInfoRow :label="t('ram')" :value="ram" />
<VtsQuickInfoRow :label="t('tags')">
</VtsKeyValueRow>
</VtsKeyValueList>
<VtsKeyValueList>
<VtsKeyValueRow :label="t('vcpus')" :value="String(vm.CPUs.number)" />
<VtsKeyValueRow :label="t('ram')" :value="ram" />
<VtsKeyValueRow :label="t('tags')">
<template #value>
<UiTagsList v-if="vm.tags.length > 0">
<UiTag v-for="tag in vm.tags" :key="tag" accent="info" variant="secondary">
@@ -74,8 +83,8 @@
</UiTag>
</UiTagsList>
</template>
</VtsQuickInfoRow>
</VtsQuickInfoColumn>
</VtsKeyValueRow>
</VtsKeyValueList>
</VtsQuickInfoCard>
</template>
@@ -87,9 +96,9 @@ import { useXoVmUtils } from '@/modules/vm/composables/xo-vm-utils.composable.ts
import { useXoVmCollection, type FrontXoVm } from '@/modules/vm/remote-resources/use-xo-vm-collection.ts'
import { XCP_LINKS } from '@/shared/constants.ts'
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import VtsKeyValueList from '@core/components/key-value-list/VtsKeyValueList.vue'
import VtsKeyValueRow from '@core/components/key-value-row/VtsKeyValueRow.vue'
import VtsQuickInfoCard from '@core/components/quick-info-card/VtsQuickInfoCard.vue'
import VtsQuickInfoColumn from '@core/components/quick-info-column/VtsQuickInfoColumn.vue'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiTag from '@core/components/ui/tag/UiTag.vue'
import UiTagsList from '@core/components/ui/tag/UiTagsList.vue'

View File

@@ -1,8 +1,8 @@
<template>
<UiCard class="vm-snapshot-card">
<UiCardTitle>{{ title }}</UiCardTitle>
<div class="snapshot-row-container">
<VtsQuickInfoRow :label="t('snapshot')" class="snapshot-row">
<VtsKeyValueList class="snapshot-row-container">
<VtsKeyValueRow :label="t('snapshot')" class="snapshot-row">
<template #value>
<UiLink
v-if="snapshot?.name_label"
@@ -13,14 +13,14 @@
{{ snapshot.name_label }}
</UiLink>
</template>
</VtsQuickInfoRow>
</VtsKeyValueRow>
<VtsCopyButton v-if="snapshot?.name_label" :value="snapshot.name_label" class="copy-button" />
</div>
<VtsQuickInfoRow :label="t('snapshot-created-on')">
<template #value>
<span v-if="formattedDate">{{ formattedDate }}</span>
</template>
</VtsQuickInfoRow>
<VtsKeyValueRow :label="t('snapshot-created-on')">
<template #value>
<span v-if="formattedDate">{{ formattedDate }}</span>
</template>
</VtsKeyValueRow>
</VtsKeyValueList>
</UiCard>
</template>
@@ -28,7 +28,8 @@
import type { FrontXoVmSnapshot } from '@/modules/snapshot/components/remote-resources/use-xo-vm-snapshot-collection.ts'
import { useXo5VmSnapshotRoute } from '@/modules/snapshot/composables/xo-vm-snapshot-route-xo5.composable.ts'
import VtsCopyButton from '@core/components/copy-button/VtsCopyButton.vue'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsKeyValueList from '@core/components/key-value-list/VtsKeyValueList.vue'
import VtsKeyValueRow from '@core/components/key-value-row/VtsKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiCardTitle from '@core/components/ui/card-title/UiCardTitle.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
@@ -60,7 +61,7 @@ const { buildXo5VmSnapshotRoute } = useXo5VmSnapshotRoute()
.copy-button {
position: absolute;
inset-block-start: 0;
inset-block-start: -0.2rem;
inset-inline-end: 0;
}
}

View File

@@ -3,25 +3,28 @@
<UiTitle>
{{ t('general-information') }}
</UiTitle>
<VtsQuickInfoRow :label="t('name')" :value="vm.name_label" />
<VtsQuickInfoRow :label="t('id')" :value="vm.id" />
<VtsQuickInfoRow :label="t('description')" :value="vm.name_description" />
<VtsQuickInfoRow :label="t('tags')">
<template v-if="vm.tags.length > 0" #value>
<UiTagsList>
<UiTag v-for="tag in vm.tags" :key="tag" accent="info" variant="secondary">{{ tag }}</UiTag>
</UiTagsList>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('os-name')" :value="vm.os_version?.name" />
<VtsQuickInfoRow :label="t('os-kernel')" :value="vm.os_version?.uname" />
<VtsQuickInfoRow :label="t('management-agent-version')" :value="vm.pvDriversVersion" />
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('name')" :value="vm.name_label" />
<VtsTabularKeyValueRow :label="t('id')" :value="vm.id" />
<VtsTabularKeyValueRow :label="t('description')" :value="vm.name_description" />
<VtsTabularKeyValueRow :label="t('tags')">
<template v-if="vm.tags.length > 0" #value>
<UiTagsList>
<UiTag v-for="tag in vm.tags" :key="tag" accent="info" variant="secondary">{{ tag }}</UiTag>
</UiTagsList>
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('os-name')" :value="vm.os_version?.name" />
<VtsTabularKeyValueRow :label="t('os-kernel')" :value="vm.os_version?.uname" />
<VtsTabularKeyValueRow :label="t('management-agent-version')" :value="vm.pvDriversVersion" />
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import type { FrontXoVm } from '@/modules/vm/remote-resources/use-xo-vm-collection.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTag from '@core/components/ui/tag/UiTag.vue'
import UiTagsList from '@core/components/ui/tag/UiTagsList.vue'

View File

@@ -3,23 +3,26 @@
<UiTitle>
{{ t('graphics-display') }}
</UiTitle>
<VtsQuickInfoRow :label="t('vga')">
<template #value>
<VtsStatus :status="vm.vga === 'std'" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('video-ram')">
<template v-if="videoRamValue?.value" #value>
{{ `${videoRamValue.value} ${videoRamValue.prefix || t('bytes:mi')}` }}
</template>
</VtsQuickInfoRow>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('vga')">
<template #value>
<VtsStatus :status="vm.vga === 'std'" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('video-ram')">
<template v-if="videoRamValue?.value" #value>
{{ `${videoRamValue.value} ${videoRamValue.prefix || t('bytes:mi')}` }}
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import type { FrontXoVm } from '@/modules/vm/remote-resources/use-xo-vm-collection.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { formatSizeRaw } from '@core/utils/size.util.ts'

View File

@@ -3,50 +3,53 @@
<UiTitle>
{{ t('vm-management') }}
</UiTitle>
<VtsQuickInfoRow :label="t('high-availability')">
<template #value>
<VtsStatus :status="vm.high_availability !== ''" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('affinity-host')">
<template #value>
<UiLink
v-if="vm.affinityHost"
icon="object:host"
:to="{ name: '/host/[id]/dashboard', params: { id: vm.affinityHost } }"
size="small"
>
{{ affinityHostName }}
</UiLink>
<template v-else>
{{ t('none') }}
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('high-availability')">
<template #value>
<VtsStatus :status="vm.high_availability !== ''" />
</template>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('protect-from-accidental-deletion')">
<template #value>
<VtsStatus :status="vm.blockedOperations.destroy !== undefined" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('protect-from-accidental-shutdown')">
<template #value>
<VtsStatus :status="isProtectedFromAccidentalShutdown" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('auto-power')">
<template #value>
<VtsStatus :status="vm.auto_poweron" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('start-delay')" :value="formattedStartDelay" />
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('affinity-host')">
<template #value>
<UiLink
v-if="vm.affinityHost"
icon="object:host"
:to="{ name: '/host/[id]/dashboard', params: { id: vm.affinityHost } }"
size="small"
>
{{ affinityHostName }}
</UiLink>
<template v-else>
{{ t('none') }}
</template>
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('protect-from-accidental-deletion')">
<template #value>
<VtsStatus :status="vm.blockedOperations.destroy !== undefined" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('protect-from-accidental-shutdown')">
<template #value>
<VtsStatus :status="isProtectedFromAccidentalShutdown" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('auto-power')">
<template #value>
<VtsStatus :status="vm.auto_poweron" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('start-delay')" :value="formattedStartDelay" />
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import { useXoHostCollection } from '@/modules/host/remote-resources/use-xo-host-collection.ts'
import type { FrontXoVm } from '@/modules/vm/remote-resources/use-xo-vm-collection.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'

View File

@@ -3,13 +3,16 @@
<UiTitle>
{{ t('networking') }}
</UiTitle>
<VtsQuickInfoRow :label="t('nic-type')" :value="vm.nicType" />
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('nic-type')" :value="vm.nicType" />
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import type { FrontXoVm } from '@/modules/vm/remote-resources/use-xo-vm-collection.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { useI18n } from 'vue-i18n'

View File

@@ -3,13 +3,16 @@
<UiTitle>
{{ t('resource-management') }}
</UiTitle>
<VtsQuickInfoRow v-for="{ label, value } of resources" :key="label" :label :value />
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow v-for="{ label, value } of resources" :key="label" :label :value />
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import type { FrontXoVm } from '@/modules/vm/remote-resources/use-xo-vm-collection.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { formatSizeRaw } from '@core/utils/size.util.ts'
@@ -19,10 +22,10 @@ import { useI18n } from 'vue-i18n'
const { vm } = defineProps<{ vm: FrontXoVm }>()
const { t } = useI18n()
const staticMinMemoryFormated = computed(() => formatSizeRaw(vm.memory.static[0], 0))
const staticMaxMemoryFormated = computed(() => formatSizeRaw(vm.memory.static[1], 0))
const dynamicMinMemoryFormated = computed(() => formatSizeRaw(vm.memory.dynamic[0], 0))
const dynamicMaxMemoryFormated = computed(() => formatSizeRaw(vm.memory.dynamic[1], 0))
const staticMinMemoryFormatted = computed(() => formatSizeRaw(vm.memory.static[0], 0))
const staticMaxMemoryFormatted = computed(() => formatSizeRaw(vm.memory.static[1], 0))
const dynamicMinMemoryFormatted = computed(() => formatSizeRaw(vm.memory.dynamic[0], 0))
const dynamicMaxMemoryFormatted = computed(() => formatSizeRaw(vm.memory.dynamic[1], 0))
const resources = computed(() => {
return [
@@ -57,19 +60,19 @@ const resources = computed(() => {
},
{
label: t('minimum-static-memory'),
value: `${staticMinMemoryFormated.value.value} ${staticMinMemoryFormated.value.prefix}`,
value: `${staticMinMemoryFormatted.value.value} ${staticMinMemoryFormatted.value.prefix}`,
},
{
label: t('maximum-static-memory'),
value: `${staticMaxMemoryFormated.value.value} ${staticMaxMemoryFormated.value.prefix}`,
value: `${staticMaxMemoryFormatted.value.value} ${staticMaxMemoryFormatted.value.prefix}`,
},
{
label: t('minimum-dynamic-memory'),
value: `${dynamicMinMemoryFormated.value.value} ${dynamicMinMemoryFormated.value.prefix}`,
value: `${dynamicMinMemoryFormatted.value.value} ${dynamicMinMemoryFormatted.value.prefix}`,
},
{
label: t('maximum-dynamic-memory'),
value: `${dynamicMaxMemoryFormated.value.value} ${dynamicMaxMemoryFormated.value.prefix}`,
value: `${dynamicMaxMemoryFormatted.value.value} ${dynamicMaxMemoryFormatted.value.prefix}`,
},
{
label: t('gpus'),

View File

@@ -3,13 +3,16 @@
<UiTitle>
{{ t('storage-configuration') }}
</UiTitle>
<VtsQuickInfoRow :label="t('suspend-storage-repository')" :value="vm.suspendSr ?? t('none')" />
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('suspend-storage-repository')" :value="vm.suspendSr ?? t('none')" />
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import type { FrontXoVm } from '@/modules/vm/remote-resources/use-xo-vm-collection.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { useI18n } from 'vue-i18n'

View File

@@ -3,36 +3,39 @@
<UiTitle>
{{ t('virtualization-boot-settings') }}
</UiTitle>
<VtsQuickInfoRow :label="t('virtualization-mode')" :value="vm.virtualizationMode" />
<VtsQuickInfoRow :label="t('secure-boot')">
<template #value>
<VtsStatus :status="vm.secureBoot" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('boot-firmware')" :value="vm.boot?.firmware" />
<VtsQuickInfoRow :label="t('virtual-tpm')" :value="vm.VTPMs.length > 0 ? vm.VTPMs.join(', ') : t('none')" />
<VtsQuickInfoRow :label="t('viridian')">
<template #value>
<VtsStatus :status="vm.viridian" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('manage-citrix-pv-drivers-via-windows-update')">
<template #value>
<VtsStatus :status="vm.hasVendorDevice" />
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('nested-virtualization')">
<template #value>
<VtsStatus :status="vm.isNestedVirtEnabled" />
</template>
</VtsQuickInfoRow>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('virtualization-mode')" :value="vm.virtualizationMode" />
<VtsTabularKeyValueRow :label="t('secure-boot')">
<template #value>
<VtsStatus :status="vm.secureBoot" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('boot-firmware')" :value="vm.boot?.firmware" />
<VtsTabularKeyValueRow :label="t('virtual-tpm')" :value="vm.VTPMs.length > 0 ? vm.VTPMs.join(', ') : t('none')" />
<VtsTabularKeyValueRow :label="t('viridian')">
<template #value>
<VtsStatus :status="vm.viridian" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('manage-citrix-pv-drivers-via-windows-update')">
<template #value>
<VtsStatus :status="vm.hasVendorDevice" />
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('nested-virtualization')">
<template #value>
<VtsStatus :status="vm.isNestedVirtEnabled" />
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</UiCard>
</template>
<script setup lang="ts">
import type { FrontXoVm } from '@/modules/vm/remote-resources/use-xo-vm-collection.ts'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsStatus from '@core/components/status/VtsStatus.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiTitle from '@core/components/ui/title/UiTitle.vue'
import { useI18n } from 'vue-i18n'

View File

@@ -1,5 +1,5 @@
<template>
<VtsColumns>
<VtsColumns extra-space-around>
<VtsColumn>
<HostSystemGeneralInformation :host />
<HostSystemNetworking :host />

View File

@@ -1,6 +1,6 @@
<template>
<VtsStateHero v-if="!isReady" format="card" type="busy" size="medium" />
<VtsColumns v-else>
<VtsColumns v-else extra-space-around>
<VtsColumn>
<PoolSystemGeneralInfo :pool />
<PoolSystemNetworking :pool />

View File

@@ -4,70 +4,74 @@
<!-- ABOUT -->
<div class="container">
<UiTitle>{{ t('about') }}</UiTitle>
<VtsColumns class="columns" :class="{ 'mobile-about': uiStore.isSmall }">
<VtsQuickInfoColumn>
<VtsColumns>
<VtsColumn :class="{ 'mobile-about': uiStore.isSmall }">
<div class="typo-h6">{{ t('xen-orchestra') }}</div>
<VtsQuickInfoRow :label="t('version')" />
<VtsQuickInfoRow :label="t('news')">
<template #value>
<UiLink size="medium" :href="XO_LINKS.BLOG">
{{ t('news-name', { name: t('xen-orchestra') }) }}
</UiLink>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('community')">
<template #value>
<UiLink size="medium" :href="XO_LINKS.COMMUNITY">
{{ t('community-name', { name: t('xen-orchestra') }) }}
</UiLink>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('documentation')">
<template #value>
<UiLink size="medium" :href="XO_LINKS.DOC">
{{ t('documentation-name', { name: t('xen-orchestra') }) }}
</UiLink>
</template>
</VtsQuickInfoRow>
</VtsQuickInfoColumn>
<VtsQuickInfoColumn>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('version')" />
<VtsTabularKeyValueRow :label="t('news')">
<template #value>
<UiLink size="medium" :href="XO_LINKS.BLOG">
{{ t('news-name', { name: t('xen-orchestra') }) }}
</UiLink>
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('community')">
<template #value>
<UiLink size="medium" :href="XO_LINKS.COMMUNITY">
{{ t('community-name', { name: t('xen-orchestra') }) }}
</UiLink>
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('documentation')">
<template #value>
<UiLink size="medium" :href="XO_LINKS.DOC">
{{ t('documentation-name', { name: t('xen-orchestra') }) }}
</UiLink>
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</VtsColumn>
<VtsColumn>
<div class="typo-h6">{{ t('xcp-ng') }}</div>
<VtsQuickInfoRow :label="t('news')">
<template #value>
<UiLink size="medium" :href="XCP_LINKS.BLOG">
{{ t('news-name', { name: t('xcp-ng') }) }}
</UiLink>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('community')">
<template #value>
<UiLink size="medium" :href="XCP_LINKS.COMMUNITY">
{{ t('community-name', { name: t('xcp-ng') }) }}
</UiLink>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('documentation')">
<template #value>
<UiLink size="medium" :href="XCP_LINKS.DOC">
{{ t('documentation-name', { name: t('xcp-ng') }) }}
</UiLink>
</template>
</VtsQuickInfoRow>
<VtsQuickInfoRow :label="t('support')">
<template #value>
<UiLink size="medium" :href="XCP_LINKS.SUPPORT">
{{ t('pro-support', { name: t('xcp-ng') }) }}
</UiLink>
</template>
</VtsQuickInfoRow>
</VtsQuickInfoColumn>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('news')">
<template #value>
<UiLink size="medium" :href="XCP_LINKS.BLOG">
{{ t('news-name', { name: t('xcp-ng') }) }}
</UiLink>
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('community')">
<template #value>
<UiLink size="medium" :href="XCP_LINKS.COMMUNITY">
{{ t('community-name', { name: t('xcp-ng') }) }}
</UiLink>
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('documentation')">
<template #value>
<UiLink size="medium" :href="XCP_LINKS.DOC">
{{ t('documentation-name', { name: t('xcp-ng') }) }}
</UiLink>
</template>
</VtsTabularKeyValueRow>
<VtsTabularKeyValueRow :label="t('support')">
<template #value>
<UiLink size="medium" :href="XCP_LINKS.SUPPORT">
{{ t('pro-support', { name: t('xcp-ng') }) }}
</UiLink>
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</VtsColumn>
</VtsColumns>
</div>
<!-- APPEARANCE -->
<div class="container">
<UiTitle>{{ t('appearance') }}</UiTitle>
<VtsColumns>
<div class="typo-h6">{{ t('mode') }}</div>
<div>
<div class="typo-h6 title">{{ t('mode') }}</div>
<!-- TODO replace this part when the component is available -->
<div class="color-modes">
<div
@@ -94,9 +98,9 @@
</span>
</div>
</div>
</VtsColumns>
<VtsColumns>
<div class="typo-h6">{{ t('theme') }}</div>
</div>
<div>
<div class="typo-h6 title">{{ t('theme') }}</div>
<div class="themes">
<div
v-for="theme in themes"
@@ -113,27 +117,31 @@
<span class="typo-body-regular-small theme-description">{{ t(theme.description) }}</span>
</div>
</div>
</VtsColumns>
</div>
</div>
<!-- LANGUAGE -->
<div class="container">
<UiTitle>{{ t('language-preferences') }}</UiTitle>
<VtsColumns class="columns" :class="{ 'mobile-language': uiStore.isSmall }">
<VtsQuickInfoColumn class="language">
<VtsInputWrapper :label="t('language')">
<VtsSelect :id="localeSelectId" accent="brand" />
<UiInfo accent="info" wrap>{{ t('untranslated-text-helper') }}</UiInfo>
</VtsInputWrapper>
</VtsQuickInfoColumn>
<VtsQuickInfoColumn>
<VtsQuickInfoRow :label="t('translation-tool')">
<template #value>
<UiLink size="medium" :href="XO_LINKS.TRANSLATION">
{{ t('weblate') }}
</UiLink>
</template>
</VtsQuickInfoRow>
</VtsQuickInfoColumn>
<VtsColumns>
<VtsColumn :class="{ 'mobile-language': uiStore.isSmall }">
<div class="language">
<VtsInputWrapper :label="t('language')">
<VtsSelect :id="localeSelectId" accent="brand" />
<UiInfo accent="info" wrap>{{ t('untranslated-text-helper') }}</UiInfo>
</VtsInputWrapper>
</div>
</VtsColumn>
<VtsColumn>
<VtsTabularKeyValueList>
<VtsTabularKeyValueRow :label="t('translation-tool')">
<template #value>
<UiLink size="medium" :href="XO_LINKS.TRANSLATION">
{{ t('weblate') }}
</UiLink>
</template>
</VtsTabularKeyValueRow>
</VtsTabularKeyValueList>
</VtsColumn>
</VtsColumns>
</div>
</UiCard>
@@ -142,12 +150,13 @@
<script setup lang="ts">
import { useTheme } from '@/shared/composables/theme.composable.ts'
import { XCP_LINKS, XO_LINKS } from '@/shared/constants.ts'
import VtsColumns from '@core/components/column/VtsColumn.vue'
import VtsColumn from '@core/components/column/VtsColumn.vue'
import VtsColumns from '@core/components/columns/VtsColumns.vue'
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import VtsInputWrapper from '@core/components/input-wrapper/VtsInputWrapper.vue'
import VtsQuickInfoColumn from '@core/components/quick-info-column/VtsQuickInfoColumn.vue'
import VtsQuickInfoRow from '@core/components/quick-info-row/VtsQuickInfoRow.vue'
import VtsSelect from '@core/components/select/VtsSelect.vue'
import VtsTabularKeyValueList from '@core/components/tabular-key-value-list/VtsTabularKeyValueList.vue'
import VtsTabularKeyValueRow from '@core/components/tabular-key-value-row/VtsTabularKeyValueRow.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiHeadBar from '@core/components/ui/head-bar/UiHeadBar.vue'
import UiInfo from '@core/components/ui/info/UiInfo.vue'
@@ -193,18 +202,9 @@ const { id: localeSelectId } = useFormSelect(availableLocales, {
display: flex;
flex-direction: column;
gap: 1.6rem;
}
.columns {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr));
gap: 8rem;
&.mobile-about {
gap: 2.4rem;
}
&.mobile-language {
gap: 4rem;
.title {
margin-block-end: 0.8rem;
}
}

View File

@@ -1,10 +1,14 @@
<template>
<div class="snapshots" :class="{ mobile: uiStore.isSmall }">
<div>
<div class="row">
<VmSnapshotCard class="last-snapshot" :snapshot="lastSnapshot" :title="t('last-snapshot')" />
<VmSnapshotCard class="last-revert" :snapshot="lastRevertSnapshot" :title="t('last-revert')" />
</div>
<VtsColumns extra-space-around>
<VtsColumn>
<VmSnapshotCard :snapshot="lastSnapshot" :title="t('last-snapshot')" />
</VtsColumn>
<VtsColumn>
<VmSnapshotCard :snapshot="lastRevertSnapshot" :title="t('last-revert')" />
</VtsColumn>
</VtsColumns>
<UiCard class="container">
<SnapshotsTable :snapshots :vm />
</UiCard>
@@ -27,6 +31,8 @@ import {
} from '@/modules/snapshot/components/remote-resources/use-xo-vm-snapshot-collection.ts'
import VmSnapshotCard from '@/modules/vm/components/snapshot/cards/VmSnapshotCard.vue'
import type { FrontXoVm } from '@/modules/vm/remote-resources/use-xo-vm-collection.ts'
import VtsColumn from '@core/components/column/VtsColumn.vue'
import VtsColumns from '@core/components/columns/VtsColumns.vue'
import VtsStateHero from '@core/components/state-hero/VtsStateHero.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiPanel from '@core/components/ui/panel/UiPanel.vue'

View File

@@ -1,5 +1,5 @@
<template>
<VtsColumns>
<VtsColumns extra-space-around>
<VtsColumn>
<VmSystemGeneralInfo :vm />
<VmSystemNetworking :vm />

View File

@@ -11,6 +11,8 @@
> Users must be able to say: "Nice enhancement, I'm eager to test it"
- [System] Update system pages layout ([user feedback](https://feedback.vates.tech/posts/37/xo6-ui-very-messy-columns-width-in-vm-system-far-better-in-xo5)) (PR [#9746](https://github.com/vatesfr/xen-orchestra/pull/9746))
### Bug fixes
> Users must be able to say: "I had this issue, happy to know it's fixed"
@@ -31,4 +33,7 @@
<!--packages-start-->
- @xen-orchestra/web minor
- @xen-orchestra/web-core minor
<!--packages-end-->

View File

@@ -2782,10 +2782,10 @@
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.8.0.tgz#cee43d801fcef9644b11b8194857695acd5f815a"
integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==
"@nodable/entities@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@nodable/entities/-/entities-1.1.0.tgz#f98e5ee5a6e987b4cad56eb97be81043d9b8d31d"
integrity sha512-bidpxmTBP0pOsxULw6XlxzQpTgrAGLDHGBK/JuWhPDL6ZV0GZ/PmN9CA9do6e+A9lYI6qx6ikJUtJYRxup141g==
"@nodable/entities@^2.1.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@nodable/entities/-/entities-2.1.0.tgz#f543e5c6446720d4cf9e498a83019dd159973bc2"
integrity sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==
"@node-saml/node-saml@^5.1.0":
version "5.1.0"
@@ -10277,7 +10277,7 @@ fast-uri@^3.0.1:
resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.0.tgz#66eecff6c764c0df9b762e62ca7edcfb53b4edfa"
integrity sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==
fast-xml-builder@^1.1.4:
fast-xml-builder@^1.1.4, fast-xml-builder@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/fast-xml-builder/-/fast-xml-builder-1.1.5.tgz#50188e1452a5fa095f415d3e63dcac0a1dbcbf11"
integrity sha512-4TJn/8FKLeslLAH3dnohXqE3QSoxkhvaMzepOIZytwJXZO69Bfz0HBdDHzOTOon6G59Zrk6VQ2bEiv1t61rfkA==
@@ -10301,12 +10301,12 @@ fast-xml-parser@^4.0.0:
strnum "^1.0.5"
fast-xml-parser@^5.5.9:
version "5.6.0"
resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-5.6.0.tgz#4ade6df478c2532a462b693278fa6393c295a9e3"
integrity sha512-5G+uaEBbOm9M4dgMOV3K/rBzfUNGqGqoUTaYJM3hBwM8t71w07gxLQZoTsjkY8FtfjabqgQHEkeIySBDYeBmJw==
version "5.7.0"
resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-5.7.0.tgz#b93e49a3d62a8824c5212d8fa099ac2e548d548a"
integrity sha512-MTcrUoRQ1GSQ9iG3QJzBGquYYYeA7piZaJoIWbPFGbRn6Jj6z7xgoAyi4DrZX4y2ZIQQBF59gc/zmvvejjgoFQ==
dependencies:
"@nodable/entities" "^1.1.0"
fast-xml-builder "^1.1.4"
"@nodable/entities" "^2.1.0"
fast-xml-builder "^1.1.5"
path-expression-matcher "^1.5.0"
strnum "^2.2.3"