Compare commits

...

7 Commits

Author SHA1 Message Date
unel
abc3018b66 feat(uiObjectLink): replace all uiObjectLink by uiLink 2026-04-27 14:22:45 +02:00
unel
423f00fefa rebase 2026-04-27 14:22:45 +02:00
unel
7456ab9faf feedback 2026-04-27 14:22:02 +02:00
unel
4d30d43a66 add changelog 2026-04-27 14:22:01 +02:00
unel
d1f3efc57f feat(xo6): rebase and resolve comment 2026-04-27 14:22:01 +02:00
unel
1d881fe8cc feat(xo6/uiLink): wrap uiLink on side panel 2026-04-27 14:22:01 +02:00
unel
7a9de0de57 feat(xo6/uiLink): add text ellipsis on uiLink 2026-04-27 14:21:56 +02:00
39 changed files with 140 additions and 175 deletions

View File

@@ -1,5 +1,9 @@
# ChangeLog
## **next**
- [XoLite] Add ellipsis on link (PR [#9234](https://github.com/vatesfr/xen-orchestra/pull/9234))
## **0.20.0** (2026-04-01)
- [VM/New] Added secureBoot support (PR [#9423](https://github.com/vatesfr/xen-orchestra/pull/9423))

View File

@@ -189,7 +189,11 @@ const mainIpAddress = computed(() => {
.host-name {
display: flex;
align-items: center;
gap: 1rem;
gap: 0.8rem;
}
.host-name {
min-width: 0;
}
}
</style>

View File

@@ -37,9 +37,7 @@
<VtsCardRowKeyValue v-bind="properties">
<template #key>Network</template>
<template #value>
<UiObjectLink route="`/vm/test/console`" icon="object:network:connected">
<span>Network Name</span>
</UiObjectLink>
<UiLink size="small" icon="object:network:connected" to="/vm/test/console">Network Name</UiLink>
</template>
<template #addons>
<UiButtonIcon icon="fa:copy" size="small" accent="brand" />
@@ -81,7 +79,7 @@ import VtsCopyButton from '@core/components/copy-button/VtsCopyButton.vue'
import UiButtonIcon from '@core/components/ui/button-icon/UiButtonIcon.vue'
import UiCard from '@core/components/ui/card/UiCard.vue'
import UiInfo from '@core/components/ui/info/UiInfo.vue'
import UiObjectLink from '@core/components/ui/object-link/UiObjectLink.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

@@ -17,12 +17,7 @@
<UiAlarmList>
<UiAlarmItem v-bind="properties">
<template #link>
<UiObjectLink route="#">
<template #icon>
<VtsIcon size="medium" name="object:vm:running" />
</template>
VM1
</UiObjectLink>
<UiLink to="#" size="medium" icon="object:vm:running">VM1</UiLink>
</template>
</UiAlarmItem>
</UiAlarmList>
@@ -32,8 +27,7 @@
<script setup lang="ts">
import ComponentStory from '@/components/component-story/ComponentStory.vue'
import { prop, slot } from '@/libs/story/story-param'
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import UiAlarmItem from '@core/components/ui/alarm-item/UiAlarmItem.vue'
import UiAlarmList from '@core/components/ui/alarm-list/UiAlarmList.vue'
import UiObjectLink from '@core/components/ui/object-link/UiObjectLink.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
</script>

View File

@@ -4,32 +4,17 @@
<UiAlarmList>
<UiAlarmItem label="Label" :percent="93.2" size="large" :description :date="Date.now()">
<template #link>
<UiObjectLink route="#">
<template #icon>
<VtsIcon size="medium" name="object:vm:running" />
</template>
VM1
</UiObjectLink>
<UiLink to="#" size="medium" icon="object:vm:running">vm1</UiLink>
</template>
</UiAlarmItem>
<UiAlarmItem label="Label" :percent="93.2" size="large" :description :date="Date.now()">
<template #link>
<UiObjectLink route="#">
<template #icon>
<VtsIcon size="medium" name="object:vm:running" />
</template>
VM1
</UiObjectLink>
<UiLink to="#" size="medium" icon="object:vm:running">vm2</UiLink>
</template>
</UiAlarmItem>
<UiAlarmItem label="Label" :percent="93.2" size="large" :description :date="Date.now()">
<template #link>
<UiObjectLink route="#">
<template #icon>
<VtsIcon size="medium" name="object:vm:running" />
</template>
VM1
</UiObjectLink>
<UiLink to="#" size="medium" icon="object:vm:running">vm3</UiLink>
</template>
</UiAlarmItem>
</UiAlarmList>
@@ -40,10 +25,9 @@
<script setup lang="ts">
import ComponentStory from '@/components/component-story/ComponentStory.vue'
import { slot } from '@/libs/story/story-param'
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import UiAlarmItem from '@core/components/ui/alarm-item/UiAlarmItem.vue'
import UiAlarmList from '@core/components/ui/alarm-list/UiAlarmList.vue'
import UiObjectLink from '@core/components/ui/object-link/UiObjectLink.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import { ref } from 'vue'
const description = ref(

View File

@@ -8,6 +8,7 @@
iconProp(),
prop('disabled').bool().widget(),
prop('target').enum('_blank', '_self').widget(),
prop('wrap').bool().widget().help('Control whether the link wraps. If not, the text has ellipsis.'),
]"
>
<UiLink v-bind="properties">This is a link</UiLink>

View File

@@ -1,21 +0,0 @@
<template>
<ComponentStory
v-slot="{ properties, settings }"
:params="[
prop('route').type('RouteLocationRaw').preset('#'),
prop('disabled').bool().widget(),
iconProp().preset('object:pool'),
slot().help('Meant to receive the object\'s label'),
slot('icon').help('Meant to receive a UiIcon or ObjectIcon component'),
setting('label').preset('Pool name').widget(),
]"
>
<UiObjectLink v-bind="properties">{{ settings.label }}</UiObjectLink>
</ComponentStory>
</template>
<script lang="ts" setup>
import ComponentStory from '@/components/component-story/ComponentStory.vue'
import { iconProp, prop, setting, slot } from '@/libs/story/story-param'
import UiObjectLink from '@core/components/ui/object-link/UiObjectLink.vue'
</script>

View File

@@ -21,7 +21,7 @@
{{ settings.label }}
<template #description>{{ settings.description }}</template>
<template #actions>
<UiObjectLink v-if="settings.showLink" class="link typo-body-regular" route="#">See tasks</UiObjectLink>
<UiLink v-if="settings.showLink" class="link typo-body-regular" to="#" size="small">See tasks</UiLink>
<UiButton v-else variant="tertiary" size="medium" :accent="properties.accent === 'danger' ? 'danger' : 'brand'">
{{ settings.actions }}
</UiButton>
@@ -35,6 +35,6 @@ import ComponentStory from '@/components/component-story/ComponentStory.vue'
import { prop, setting, slot } from '@/libs/story/story-param'
import { boolean, text } from '@/libs/story/story-widget'
import UiButton from '@core/components/ui/button/UiButton.vue'
import UiObjectLink from '@core/components/ui/object-link/UiObjectLink.vue'
import UiLink from '@core/components/ui/link/UiLink.vue'
import UiToaster from '@core/components/ui/toaster/UiToaster.vue'
</script>

View File

@@ -109,7 +109,6 @@ declare module 'vue-router/auto-routes' {
'/story/web-core/ui/link/ui-link': RouteRecordInfo<'/story/web-core/ui/link/ui-link', '/story/web-core/ui/link/ui-link', Record<never, never>, Record<never, never>>,
'/story/web-core/ui/log-entry-viewer/ui-log-entry-viewer': RouteRecordInfo<'/story/web-core/ui/log-entry-viewer/ui-log-entry-viewer', '/story/web-core/ui/log-entry-viewer/ui-log-entry-viewer', Record<never, never>, Record<never, never>>,
'/story/web-core/ui/logo-text/ui-logo-text': RouteRecordInfo<'/story/web-core/ui/logo-text/ui-logo-text', '/story/web-core/ui/logo-text/ui-logo-text', Record<never, never>, Record<never, never>>,
'/story/web-core/ui/object-link/ui-object-link': RouteRecordInfo<'/story/web-core/ui/object-link/ui-object-link', '/story/web-core/ui/object-link/ui-object-link', Record<never, never>, Record<never, never>>,
'/story/web-core/ui/panel/ui-panel': RouteRecordInfo<'/story/web-core/ui/panel/ui-panel', '/story/web-core/ui/panel/ui-panel', Record<never, never>, Record<never, never>>,
'/story/web-core/ui/progress-bar/ui-progress-bar': RouteRecordInfo<'/story/web-core/ui/progress-bar/ui-progress-bar', '/story/web-core/ui/progress-bar/ui-progress-bar', Record<never, never>, Record<never, never>>,
'/story/web-core/ui/query-search-bar/ui-query-search-bar': RouteRecordInfo<'/story/web-core/ui/query-search-bar/ui-query-search-bar', '/story/web-core/ui/query-search-bar/ui-query-search-bar', Record<never, never>, Record<never, never>>,

View File

@@ -134,8 +134,10 @@ watch(
display: flex;
align-items: end;
gap: 0.8rem;
min-width: 0;
.value {
min-width: 0;
color: var(--color-neutral-txt-primary);
}

View File

@@ -39,6 +39,7 @@ const slots = defineSlots<{
align-items: center;
gap: 1.6rem;
color: var(--color-neutral-txt-primary);
min-width: 0;
}
.info {

View File

@@ -1,15 +1,27 @@
<!-- v3 -->
<template>
<component :is="component" :class="classes" class="ui-link" v-bind="attributes">
<VtsIcon :name="icon" size="medium" />
<slot />
<VtsIcon v-if="attributes.target === '_blank'" name="fa:up-right-from-square" size="medium" class="external-icon" />
<span>
<VtsIcon :name="icon" size="medium" />
</span>
<span v-tooltip :class="wrap == true ? 'link-wrap' : 'text-ellipsis'">
<slot />
</span>
<span>
<VtsIcon
v-if="attributes.target === '_blank'"
name="fa:up-right-from-square"
size="medium"
class="external-icon"
/>
</span>
</component>
</template>
<script lang="ts" setup>
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import { type LinkOptions, useLinkComponent } from '@core/composables/link-component.composable'
import { vTooltip } from '@core/directives/tooltip.directive'
import type { IconName } from '@core/icons'
import { computed } from 'vue'
@@ -17,6 +29,7 @@ const props = defineProps<
LinkOptions & {
size: 'small' | 'medium'
icon?: IconName
wrap?: boolean
}
>()
@@ -33,9 +46,10 @@ const classes = computed(() => [typoClasses[props.size], { disabled: isDisabled.
<style lang="postcss" scoped>
.ui-link {
display: inline-flex;
align-items: center;
gap: 0.8rem;
color: var(--color-brand-txt-base);
min-width: 0;
max-width: 100%;
&:hover {
color: var(--color-brand-txt-hover);
@@ -62,12 +76,18 @@ const classes = computed(() => [typoClasses[props.size], { disabled: isDisabled.
cursor: not-allowed;
}
.link-wrap {
text-wrap: wrap;
overflow-wrap: anywhere;
}
&:not([href]) {
text-decoration: none;
cursor: default;
}
.external-icon {
margin: calc((1em - 0.75em) / 2) 0;
font-size: 0.75em;
}
}

View File

@@ -1,83 +0,0 @@
<!-- v3 -->
<template>
<RouterLink v-if="route && !disabled" :to="route" class="ui-object-link is-link typo-action-link-small">
<span class="icon">
<slot name="icon">
<VtsIcon :name="icon" size="medium" />
</slot>
</span>
<span v-tooltip class="content text-ellipsis">
<slot />
</span>
</RouterLink>
<span v-else :class="{ disabled }" class="ui-object-link typo-action-link-small">
<span class="icon">
<slot name="icon">
<VtsIcon :name="icon" size="medium" />
</slot>
</span>
<slot />
</span>
</template>
<script lang="ts" setup>
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import { vTooltip } from '@core/directives/tooltip.directive'
import type { IconName } from '@core/icons'
import { type RouteLocationRaw } from 'vue-router'
defineProps<{
route?: RouteLocationRaw
disabled?: boolean
icon?: IconName
}>()
defineSlots<{
default(): any
icon(): any
}>()
</script>
<style lang="postcss" scoped>
.ui-object-link {
display: flex;
min-width: 0;
align-items: center;
color: var(--color-brand-txt-base);
gap: 1rem;
&.disabled {
color: var(--color-neutral-txt-secondary);
cursor: not-allowed;
}
.icon {
color: var(--color-neutral-txt-primary);
font-size: 1.6rem;
}
/* INTERACTION VARIANTS */
&.is-link {
&:hover {
color: var(--color-brand-txt-hover);
}
&:active {
color: var(--color-brand-txt-active);
}
&:focus-visible {
outline: none;
&::before {
content: '';
position: absolute;
inset: -0.6rem;
border: 0.2rem solid var(--color-brand-txt-base);
border-radius: 0.4rem;
}
}
}
}
</style>

View File

@@ -6,6 +6,7 @@
size="small"
icon="object:backup-job"
:to="{ name: '/backup/[id]/runs', params: { id: backupJob.id } }"
wrap
>
{{ backupJob.name }}
</UiLink>

View File

@@ -49,8 +49,9 @@
<VtsCardRowKeyValue v-if="backupLog.tasks !== undefined && backupLog.tasks.length > 0">
<template #key>{{ t('task') }}</template>
<template #value>
<!-- TODO: add link to task when Tasks page will be available -->
<UiLink size="small">{{ backupLog.tasks[0].id }}</UiLink>
<UiLink size="small" :to="{ path: '/tasks', query: { id: backupLog.tasks[0].id } }" wrap>
{{ backupLog.tasks[0].id }}
</UiLink>
</template>
</VtsCardRowKeyValue>
</div>

View File

@@ -4,7 +4,7 @@
{{ label }}
</template>
<template #value>
<UiLink size="small" icon="object:pool" :to="{ name: '/pool/[id]/dashboard', params: { id: pool.id } }">
<UiLink size="small" icon="object:pool" :to="{ name: '/pool/[id]/dashboard', params: { id: pool.id } }" wrap>
{{ pool.name_label }}
</UiLink>
</template>

View File

@@ -1,6 +1,6 @@
<template>
<li>
<UiLink size="small" :icon :href>
<UiLink size="small" :icon :href wrap>
{{ br.name }}
</UiLink>
</li>

View File

@@ -1,6 +1,6 @@
<template>
<li>
<UiLink size="small" :icon="srStatusIcon" :href>
<UiLink size="small" :icon="srStatusIcon" :href wrap>
{{ sr.name_label }}
</UiLink>
</li>

View File

@@ -9,6 +9,7 @@
size="small"
icon="object:backup-run"
:to="{ name: '/backup/[id]/runs', params: { id: backupRun.jobId }, query: { id: backupRun.id } }"
wrap
>
{{ backupRun.id }}
</UiLink>
@@ -41,7 +42,7 @@
{{ t('schedule') }}
</template>
<template #value>
<UiLink size="small" icon="object:backup-schedule" :href>
<UiLink size="small" icon="object:backup-schedule" :href wrap>
{{ scheduleName || backupRun.jobId }}
</UiLink>
</template>

View File

@@ -7,7 +7,7 @@
<div>
<UiCollapsibleList tag="ul" :total-items="backedUpPools.length">
<li v-for="pool in backedUpPools" :key="pool.id">
<UiLink size="small" icon="object:pool" :to="{ name: '/pool/[id]/dashboard', params: { id: pool.id } }">
<UiLink size="small" icon="object:pool" :to="{ name: '/pool/[id]/dashboard', params: { id: pool.id } }" wrap>
{{ pool.name_label }}
</UiLink>
</li>

View File

@@ -60,6 +60,7 @@
size="small"
:icon="`object:vm:${toLower(vm.power_state)}`"
:to="{ name: '/vm/[id]/dashboard', params: { id: vm.id } }"
wrap
>
{{ vm.name_label }}
</UiLink>

View File

@@ -17,6 +17,7 @@
size="small"
icon="object:backup-schedule"
:href="buildXo5Route(`/backup/${schedule.jobId}/edit`)"
wrap
>
{{ schedule.name }}
</UiLink>

View File

@@ -3,7 +3,7 @@
<UiCardTitle>
{{ t('source-backup-repository') }}
</UiCardTitle>
<UiLink size="small" :icon="sourceBackupRepositoryIcon" :href>
<UiLink size="small" :icon="sourceBackupRepositoryIcon" :href wrap>
{{ sourceBackupRepository.name }}
</UiLink>
</UiCard>

View File

@@ -5,6 +5,7 @@
:to="{ name: '/host/[id]/dashboard', params: { id: host.id } }"
size="medium"
:icon="`object:host:${toLower(host.power_state)}`"
wrap
>
{{ host.name_label }}
</UiLink>
@@ -48,7 +49,12 @@
<template #key>{{ t('pool') }}</template>
<template #value>
<div v-if="pool" class="value">
<UiLink :to="{ name: '/pool/[id]/dashboard', params: { id: pool.id } }" size="small" icon="object:pool">
<UiLink
:to="{ name: '/pool/[id]/dashboard', params: { id: pool.id } }"
size="small"
icon="object:pool"
wrap
>
{{ pool.name_label }}
</UiLink>
</div>
@@ -69,6 +75,7 @@
:to="{ name: '/host/[id]/dashboard', params: { id: masterHost.id } }"
size="small"
:icon="`object:host:${toLower(masterHost.power_state)}`"
wrap
>
{{ masterHost.name_label }}
</UiLink>

View File

@@ -25,8 +25,8 @@
{{ t('network') }}
</template>
<template #value>
<UiLink v-if="network" size="medium" :to="networkTo" icon="object:network">
<span v-tooltip class="text-ellipsis">{{ network.name_label }}</span>
<UiLink v-if="network" size="medium" :to="networkTo" icon="object:network" wrap>
{{ network.name_label }}
</UiLink>
</template>
<template v-if="network" #addons>

View File

@@ -30,6 +30,7 @@
icon="object:pool"
size="small"
:to="{ name: '/pool/[id]/dashboard', params: { id: server.poolId } }"
wrap
>
{{ server.poolNameLabel }}
</UiLink>
@@ -88,6 +89,7 @@
:icon="`object:host:${toLower(primaryHost.power_state)}`"
size="small"
:to="{ name: '/host/[id]/dashboard', params: { id: primaryHost.id } }"
wrap
>
{{ primaryHost.name_label }}
<VtsIcon accent="info" name="status:primary-circle" size="medium" />
@@ -154,6 +156,7 @@
:to="{ name: '/host/[id]/dashboard', params: { id: host.id } }"
:icon="`object:host:${toLower(host.power_state)}`"
size="small"
wrap
>
{{ host.name_label }}
<VtsIcon v-if="primaryHost?.id === host.id" accent="info" name="status:primary-circle" size="medium" />

View File

@@ -1,7 +1,7 @@
<template>
<UiCard class="card-container">
<div class="content">
<UiLink icon="object:vm" size="medium" :href="buildXo5VmSnapshotRoute(snapshot.$snapshot_of, snapshot.id)">
<UiLink icon="object:vm" size="medium" :href="buildXo5VmSnapshotRoute(snapshot.$snapshot_of, snapshot.id)" wrap>
{{ snapshot.name_label }}
</UiLink>
<VtsCodeSnippet :content="snapshot.id" copy />
@@ -35,7 +35,13 @@
{{ t('trigger') }}
</template>
<template #value>
<UiLink v-if="snapshot.other?.['xo:backup:schedule']" size="small" :icon="trigger.icon" :href="trigger.href">
<UiLink
v-if="snapshot.other?.['xo:backup:schedule']"
size="small"
:icon="trigger.icon"
:href="trigger.href"
wrap
>
{{ trigger.label }}
</UiLink>
<span v-else>

View File

@@ -9,6 +9,7 @@
size="small"
icon="object:host"
:to="{ name: '/host/[id]/dashboard', params: { id: host.id } }"
wrap
>
{{ host.name_label }}
</UiLink>

View File

@@ -6,7 +6,12 @@
</UiCardTitle>
<UiCollapsibleList v-if="hosts.length > 0" tag="ul" :total-items="hosts.length">
<li v-for="host in hosts" :key="host.id" v-tooltip class="text-ellipsis">
<UiLink size="small" :icon="`object:host:${toLower(host.power_state)}`" :to="{ name: '/host/[id]/dashboard', params: { id: host.id } }">
<UiLink
size="small"
:icon="`object:host:${toLower(host.power_state)}`"
:to="{ name: '/host/[id]/dashboard', params: { id: host.id } }"
wrap
>
{{ host.name_label }}
</UiLink>
</li>

View File

@@ -1,7 +1,7 @@
<template>
<UiCard class="card-container">
<UiCardTitle>
<UiLink v-if="sr.name_label" size="small" :icon="`object:sr:${allPbdsConnectionStatus}`" :href>
<UiLink v-if="sr.name_label" size="small" :icon="`object:sr:${allPbdsConnectionStatus}`" :href wrap>
{{ sr.name_label }}
</UiLink>
</UiCardTitle>

View File

@@ -6,7 +6,7 @@
</UiCardTitle>
<UiCollapsibleList v-if="vdis.length > 0" tag="ul" :total-items="vdis.length">
<li v-for="vdi in vdis" :key="vdi.id" v-tooltip class="text-ellipsis">
<UiLink size="small" icon="object:vdi" :href="buildXo5Route(`/srs/${vdi.$SR}/disks?s=1_0_asc-${vdi.id}`)">
<UiLink size="small" icon="object:vdi" :href="buildXo5Route(`/srs/${vdi.$SR}/disks?s=1_0_asc-${vdi.id}`)" wrap>
{{ vdi.name_label }}
</UiLink>
</li>

View File

@@ -1,7 +1,7 @@
<template>
<UiCard class="card-container">
<UiCardTitle>
<UiLink v-if="task.properties.name !== undefined" size="small" icon="fa:bars-progress">
<UiLink v-if="task.properties.name !== undefined" size="small" icon="fa:bars-progress" wrap>
{{ task.properties.name }}
</UiLink>
<template v-else>{{ task.id }}</template>

View File

@@ -11,7 +11,7 @@
</template>
<template #value>
<div v-if="vdiSr" class="storage">
<UiLink size="small" :href="srHref" icon="object:sr">
<UiLink size="small" :href="srHref" icon="object:sr" wrap>
{{ vdiSr.name_label }}
</UiLink>
</div>

View File

@@ -1,6 +1,6 @@
<template>
<UiCard class="card-container">
<UiLink size="medium" :href="vdiHref" icon="object:vdi">
<UiLink size="medium" :href="vdiHref" icon="object:vdi" wrap>
{{ vdi.name_label }}
</UiLink>
<div class="content">

View File

@@ -32,7 +32,7 @@
{{ t('network') }}
</template>
<template #value>
<UiLink v-if="network" size="medium" :to="networkTo" icon="object:network">
<UiLink v-if="network" size="medium" :to="networkTo" icon="object:network" wrap>
{{ network.name_label }}
</UiLink>
</template>

View File

@@ -3,7 +3,7 @@
<VtsQuickInfoColumn>
<VtsQuickInfoRow :label="t('state')">
<template #value>
<span class="value">
<span class="power-state">
<VtsIcon :name="powerState.icon" size="medium" />
{{ powerState.text }}
</span>
@@ -18,7 +18,12 @@
<VtsQuickInfoRow :label="t('uuid')" :value="vm.id" />
<VtsQuickInfoRow :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>
@@ -29,7 +34,11 @@
<VtsQuickInfoRow :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" />
@@ -46,7 +55,7 @@
<VtsQuickInfoRow :label="t('virtualization-type')" :value="virtualizationType" />
<VtsQuickInfoRow :label="t('guest-tools')">
<template #value>
<div class="value">
<div class="guest-tools">
<VtsIcon
v-if="guestToolsDisplay.value !== '-'"
v-tooltip="guestToolsDisplay.tooltip"
@@ -136,10 +145,19 @@ const hostPowerState = computed(() =>
<style lang="postcss" scoped>
.vm-dashboard-quick-info {
.value {
.power-state,
.pool-name,
.host-name,
.guest-tools {
display: flex;
align-items: center;
gap: 0.8rem;
}
.pool-name,
.host-name,
.guest-tools {
min-width: 0;
}
}
</style>

View File

@@ -6,6 +6,7 @@
size="medium"
:icon="`object:vm:${toLower(vm.power_state)}`"
:to="{ name: '/vm/[id]/dashboard', params: { id: vm.id } }"
wrap
>
{{ vm.name_label }}
</UiLink>
@@ -43,7 +44,12 @@
<template #key>{{ t('pool') }}</template>
<template #value>
<div v-if="pool" class="value">
<UiLink :to="{ name: '/pool/[id]/dashboard', params: { id: pool.id } }" size="small" icon="object:pool">
<UiLink
:to="{ name: '/pool/[id]/dashboard', params: { id: pool.id } }"
size="small"
icon="object:pool"
wrap
>
{{ pool.name_label }}
</UiLink>
</div>
@@ -56,7 +62,12 @@
<template #key>{{ t('host') }}</template>
<template #value>
<div v-if="host" class="value">
<UiLink :to="{ name: '/host/[id]/dashboard', params: { id: host.id } }" size="small" :icon="`object:host:${hostPowerState}`">
<UiLink
:to="{ name: '/host/[id]/dashboard', params: { id: host.id } }"
size="small"
:icon="`object:host:${hostPowerState}`"
wrap
>
{{ host.name_label }}
</UiLink>
<VtsIcon v-if="isMaster" v-tooltip="t('master')" name="status:primary-circle" size="small" />
@@ -83,7 +94,7 @@
:name="guestToolsDisplay.type === 'link' ? 'status:halted-circle' : 'status:success-circle'"
size="medium"
/>
<UiLink v-if="guestToolsDisplay.type === 'link'" size="small" :href="XCP_LINKS.GUEST_TOOLS">
<UiLink v-if="guestToolsDisplay.type === 'link'" size="small" :href="XCP_LINKS.GUEST_TOOLS" wrap>
{{ guestToolsDisplay.value }}
</UiLink>
<template v-else>
@@ -97,7 +108,7 @@
<template #value>
<div class="value">
<VtsIcon name="fa:template" size="medium" />
<UiLink v-if="template" size="small" :href="xo5VmTemplateHref">
<UiLink v-if="template" size="small" :href="xo5VmTemplateHref" wrap>
{{ template.name_label }}
</UiLink>
<span v-else>{{ vm.other.base_template_name }}</span>
@@ -119,7 +130,7 @@
<template #value>
<div class="value">
<UiUserLogo size="extra-small" class="user-logo" />
<UiLink v-if="userLabel" size="small" :href="xo5UserHref">
<UiLink v-if="userLabel" size="small" :href="xo5UserHref" wrap>
{{ userLabel }}
</UiLink>
<span v-else>{{ t('unknown') }}</span>

View File

@@ -2,7 +2,12 @@
<UiCard class="card-container">
<UiCardTitle>
{{ t('networks') }}
<UiLink v-if="ipAddresses.length > 0" size="medium" :to="{ name: '/vm/[id]/networks', params: { id: vm.id } }">
<UiLink
v-if="ipAddresses.length > 0"
size="medium"
:to="{ name: '/vm/[id]/networks', params: { id: vm.id } }"
wrap
>
{{ t('see-details') }}
</UiLink>
</UiCardTitle>

View File

@@ -12,6 +12,7 @@
> Users must be able to say: "Nice enhancement, I'm eager to test it"
- [VM] Add possibility to remove a snapshot on snapshot tab (PR [#9749](https://github.com/vatesfr/xen-orchestra/pull/9749))
- [XO6] Add ellipsis on link (PR [#9234](https://github.com/vatesfr/xen-orchestra/pull/9234))
### Bug fixes