mirror of
https://github.com/vatesfr/xen-orchestra.git
synced 2026-11-09 17:06:13 -06:00
fix(xo6,lite): translate VM and host state tooltips in tree view (#10643)
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
|
||||
- [Side panels] Side panels can be resized like the treeview, whose default width now adapts to the screen size (PR [#10725](https://github.com/vatesfr/xen-orchestra/pull/10725))
|
||||
- [Side panels] Values stay next to their label when they fit and move below it otherwise, fields with several values (IP addresses, bond devices) get a copy button per value and a "Copy all" action, and rows, links and statuses are more evenly spaced and sized (PR [#10733](https://github.com/vatesfr/xen-orchestra/pull/10733))
|
||||
- [Treeview] Fix translations of the tooltip for VM and host statuses in treeview (PR [#10643](https://github.com/vatesfr/xen-orchestra/pull/10643))
|
||||
|
||||
## **0.27.0** (2026-10-29)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<VtsQuickInfoCard class="vm-dashboard-quick-info" :loading="!isReady">
|
||||
<VtsQuickInfoCard :loading="!isReady" class="vm-dashboard-quick-info">
|
||||
<VtsKeyValueList>
|
||||
<VtsKeyValueRow :label="t('state')">
|
||||
<template #value>
|
||||
@@ -19,11 +19,11 @@
|
||||
<template #value>
|
||||
<UiLink
|
||||
v-if="host"
|
||||
:to="`/host/${host.uuid}`"
|
||||
size="medium"
|
||||
:icon="hostIcon"
|
||||
:is-primary="isPoolMaster"
|
||||
:primary-tooltip="t('master')"
|
||||
:to="`/host/${host.uuid}`"
|
||||
size="medium"
|
||||
>
|
||||
{{ host.name_label }}
|
||||
</UiLink>
|
||||
@@ -54,9 +54,9 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { VM_POWER_STATE } from '@/libs/xen-api/xen-api.enums.ts'
|
||||
import type { XenApiVm } from '@/libs/xen-api/xen-api.types.ts'
|
||||
import { getHostIcon } from '@/modules/host/utils/host.util.ts'
|
||||
import { useVmUtils } from '@/modules/vm/composables/vm-utils.composable.ts'
|
||||
import { useHostMetricsStore } from '@/stores/xen-api/host-metrics.store.ts'
|
||||
import { usePoolStore } from '@/stores/xen-api/pool.store.ts'
|
||||
import { useVmGuestMetricsStore } from '@/stores/xen-api/vm-guest-metrics.store.ts'
|
||||
@@ -70,7 +70,6 @@ import VtsTag from '@core/components/tag/VtsTag.vue'
|
||||
import UiLink from '@core/components/ui/link/UiLink.vue'
|
||||
import UiTagsList from '@core/components/ui/tag/UiTagsList.vue'
|
||||
import { useTimeAgo } from '@core/composables/locale-time-ago.composable.ts'
|
||||
import { useMapper } from '@core/packages/mapper'
|
||||
import { formatSizeRaw } from '@core/utils/size.util.ts'
|
||||
import { formatDate, parseDateTime } from '@core/utils/time.util.ts'
|
||||
import { computed } from 'vue'
|
||||
@@ -98,16 +97,7 @@ const isPoolMaster = computed(() => pool.value?.master === host.value?.$ref)
|
||||
|
||||
const hostIcon = computed(() => getHostIcon(host.value, getHostPowerState(host.value)))
|
||||
|
||||
const powerState = useMapper(
|
||||
() => vm.power_state,
|
||||
{
|
||||
[VM_POWER_STATE.RUNNING]: { icon: 'status:running-circle', text: t('vm:status:running') },
|
||||
[VM_POWER_STATE.HALTED]: { icon: 'status:halted-circle', text: t('vm:status:halted') },
|
||||
[VM_POWER_STATE.PAUSED]: { icon: 'status:paused-circle', text: t('vm:status:paused') },
|
||||
[VM_POWER_STATE.SUSPENDED]: { icon: 'status:suspended-circle', text: t('vm:status:suspended') },
|
||||
},
|
||||
VM_POWER_STATE.RUNNING
|
||||
)
|
||||
const { powerState } = useVmUtils(() => vm)
|
||||
|
||||
function getValidDateTime(dateTime: string | undefined): string | undefined {
|
||||
return dateTime === '19700101T00:00:00Z' ? undefined : dateTime
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useHostMetricsStore } from '@/stores/xen-api/host-metrics.store.ts'
|
||||
import { usePoolStore } from '@/stores/xen-api/pool.store.ts'
|
||||
import type { IconName } from '@core/icons'
|
||||
import { useTimeAgo } from '@core/composables/locale-time-ago.composable.ts'
|
||||
import { useMapper } from '@core/packages/mapper'
|
||||
import { createMapper, useMapper } from '@core/packages/mapper'
|
||||
import { parseDateTime } from '@core/utils/time.util.ts'
|
||||
import { toComputed } from '@core/utils/to-computed.util.ts'
|
||||
import { HOST_POWER_STATE } from '@vates/types'
|
||||
@@ -70,20 +70,31 @@ export function useHostUtils(rawHost: MaybeRefOrGetter<XenApiHost | undefined>)
|
||||
|
||||
const currentOperation = useMapper<string, string>(
|
||||
() => pendingStateOperation.value,
|
||||
{
|
||||
() => ({
|
||||
[HOST_OPERATION.ENABLE]: t('operation:enable'),
|
||||
[HOST_OPERATION.EVACUATE]: t('operation:evacuate'),
|
||||
[HOST_OPERATION.POWER_ON]: t('operation:start'),
|
||||
[HOST_OPERATION.REBOOT]: t('operation:clean-reboot'),
|
||||
[HOST_OPERATION.SHUTDOWN]: t('operation:shutdown'),
|
||||
unknown: '',
|
||||
},
|
||||
}),
|
||||
'unknown'
|
||||
)
|
||||
|
||||
const getHostStatus = createMapper<HostState, { text: string; icon: IconName | undefined }>(
|
||||
() => ({
|
||||
running: { text: t('host:status:running'), icon: 'status:running-circle' },
|
||||
halted: { text: t('host:status:halted'), icon: 'status:halted-circle' },
|
||||
disabled: { text: t('host:status:disabled'), icon: 'status:host-disabled-circle' },
|
||||
unknown: { text: t('host:status:unknown'), icon: undefined },
|
||||
}),
|
||||
'unknown'
|
||||
)
|
||||
|
||||
return {
|
||||
isMaster,
|
||||
isRunning,
|
||||
getHostStatus,
|
||||
hostState,
|
||||
powerState,
|
||||
isChangingState,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
>
|
||||
{{ branch.data.name_label || '(Host)' }}
|
||||
<template #icon>
|
||||
<VtsObjectIcon v-tooltip="hostState" type="host" size="medium" :state="hostState" />
|
||||
<VtsObjectIcon v-tooltip="powerState.text" type="host" size="medium" :state="hostState" />
|
||||
</template>
|
||||
<template #addons>
|
||||
<UiLoader v-if="isChangingState" v-tooltip="currentOperation" />
|
||||
@@ -63,7 +63,8 @@ const { t } = useI18n()
|
||||
const { isMasterHost } = usePoolStore().subscribe()
|
||||
const { runningVmsCountByHostRef } = useVmStore().subscribe()
|
||||
|
||||
const { hostState, isChangingState, currentOperation } = useHostUtils(() => branch.data)
|
||||
const { getHostStatus, hostState, isChangingState, currentOperation } = useHostUtils(() => branch.data)
|
||||
const powerState = computed(() => getHostStatus(hostState.value))
|
||||
|
||||
const isMaster = computed(() => isMasterHost(branch.data.$ref))
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<VtsTreeItem expanded :node-id="leaf.dataId">
|
||||
<VtsTreeItem :node-id="leaf.dataId" expanded>
|
||||
<UiTreeItemLabel :route="{ name: '/vm/[uuid]', params: { uuid: leaf.data.uuid } }" no-indent>
|
||||
{{ leaf.data.name_label || '(VM)' }}
|
||||
<template #icon>
|
||||
<VtsObjectIcon size="medium" :state="powerState" type="vm" />
|
||||
<VtsObjectIcon v-tooltip="powerState.text" :state="vmState" size="medium" type="vm" />
|
||||
</template>
|
||||
<template #addons>
|
||||
<UiLoader v-if="isChangingState" v-tooltip="{ placement: 'top', content: currentOperation }" />
|
||||
@@ -11,10 +11,10 @@
|
||||
<template #trigger="{ open, isOpen }">
|
||||
<UiButtonIcon
|
||||
v-tooltip="{ placement: 'top', content: t('quick-actions') }"
|
||||
icon="action:more-actions"
|
||||
accent="brand"
|
||||
size="small"
|
||||
:selected="isOpen"
|
||||
accent="brand"
|
||||
icon="action:more-actions"
|
||||
size="small"
|
||||
@click="open($event)"
|
||||
/>
|
||||
</template>
|
||||
@@ -26,10 +26,10 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { VM_POWER_STATE } from '@/libs/xen-api/xen-api.enums.ts'
|
||||
import type { VmLeaf } from '@/modules/treeview/types/tree.type.ts'
|
||||
import VmTreeActions from '@/modules/vm/components/actions/VmTreeActions.vue'
|
||||
import { useVmOperation } from '@/modules/vm/composables/vm-operation.composable.ts'
|
||||
import { useVmUtils } from '@/modules/vm/composables/vm-utils.composable.ts'
|
||||
import MenuList from '@core/components/menu/MenuList.vue'
|
||||
import VtsObjectIcon from '@core/components/object-icon/VtsObjectIcon.vue'
|
||||
import VtsTreeItem from '@core/components/tree/VtsTreeItem.vue'
|
||||
@@ -37,6 +37,7 @@ import UiButtonIcon from '@core/components/ui/button-icon/UiButtonIcon.vue'
|
||||
import UiLoader from '@core/components/ui/loader/UiLoader.vue'
|
||||
import UiTreeItemLabel from '@core/components/ui/tree-item-label/UiTreeItemLabel.vue'
|
||||
import { vTooltip } from '@core/directives/tooltip.directive.ts'
|
||||
import { toLower } from 'lodash-es'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
@@ -47,6 +48,7 @@ const { leaf } = defineProps<{
|
||||
const { t } = useI18n()
|
||||
|
||||
const { isChangingState, currentOperation } = useVmOperation(() => leaf.data)
|
||||
const { powerState } = useVmUtils(() => leaf.data)
|
||||
|
||||
const powerState = computed(() => leaf.data.power_state.toLowerCase() as Lowercase<VM_POWER_STATE>)
|
||||
const vmState = computed(() => toLower(leaf.data.power_state))
|
||||
</script>
|
||||
|
||||
@@ -17,7 +17,7 @@ export function useVmOperation(rawVm: MaybeRefOrGetter<XenApiVm | undefined>) {
|
||||
|
||||
const currentOperation = useMapper<string, string>(
|
||||
() => Object.values(vm.value?.current_operations ?? {})[0],
|
||||
{
|
||||
() => ({
|
||||
start: t('operation:start'),
|
||||
start_on: t('operation:start-on-host'),
|
||||
pause: t('operation:pause'),
|
||||
@@ -36,7 +36,7 @@ export function useVmOperation(rawVm: MaybeRefOrGetter<XenApiVm | undefined>) {
|
||||
export: t('operation:export'),
|
||||
import: t('operation:import'),
|
||||
unknown: '',
|
||||
},
|
||||
}),
|
||||
'unknown'
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { VM_POWER_STATE } from '@/libs/xen-api/xen-api.enums.ts'
|
||||
import type { XenApiVm } from '@/libs/xen-api/xen-api.types.ts'
|
||||
import type { IconName } from '@core/icons'
|
||||
import { useMapper } from '@core/packages/mapper'
|
||||
import { toComputed } from '@core/utils/to-computed.util.ts'
|
||||
import type { MaybeRefOrGetter } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
export function useVmUtils(rawVm: MaybeRefOrGetter<XenApiVm>) {
|
||||
const { t } = useI18n()
|
||||
|
||||
const vm = toComputed(rawVm)
|
||||
|
||||
const powerState = useMapper<VM_POWER_STATE, { icon: IconName; text: string }>(
|
||||
() => vm.value.power_state,
|
||||
() => ({
|
||||
[VM_POWER_STATE.RUNNING]: { icon: 'status:running-circle', text: t('vm:status:running') },
|
||||
[VM_POWER_STATE.HALTED]: { icon: 'status:halted-circle', text: t('vm:status:halted') },
|
||||
[VM_POWER_STATE.PAUSED]: { icon: 'status:paused-circle', text: t('vm:status:paused') },
|
||||
[VM_POWER_STATE.SUSPENDED]: { icon: 'status:suspended-circle', text: t('vm:status:suspended') },
|
||||
}),
|
||||
VM_POWER_STATE.RUNNING
|
||||
)
|
||||
|
||||
return {
|
||||
powerState,
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export type VmState = 'running' | 'halted' | 'paused' | 'suspended'
|
||||
|
||||
export type HostState = 'running' | 'halted' | 'warning' | 'disabled' | 'unknown'
|
||||
@@ -1 +0,0 @@
|
||||
export type POWER_STATE = 'running' | 'paused' | 'halted' | 'suspended'
|
||||
@@ -19,12 +19,12 @@ export function useXoHostUtils(rawHost: MaybeRefOrGetter<FrontXoHost>) {
|
||||
const { vmsByHost } = useXoVmCollection()
|
||||
|
||||
const getHostStateDisplay = createMapper<XoHostState, { text: string; icon: IconName | undefined }>(
|
||||
{
|
||||
() => ({
|
||||
running: { text: t('host:status:running'), icon: 'status:running-circle' },
|
||||
halted: { text: t('host:status:halted'), icon: 'status:halted-circle' },
|
||||
disabled: { text: t('host:status:disabled'), icon: 'status:host-disabled-circle' },
|
||||
unknown: { text: t('host:status:unknown'), icon: undefined },
|
||||
},
|
||||
}),
|
||||
'unknown'
|
||||
)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<VtsTreeItem :expanded="!branch.isCollapsed" :node-id="branch.data.id" :has-children="branch.hasChildren">
|
||||
<UiTreeItemLabel icon="object:host" :route="`/host/${branch.data.id}`" @toggle="branch.toggleCollapse()">
|
||||
<VtsTreeItem :expanded="!branch.isCollapsed" :has-children="branch.hasChildren" :node-id="branch.data.id">
|
||||
<UiTreeItemLabel :route="`/host/${branch.data.id}`" icon="object:host" @toggle="branch.toggleCollapse()">
|
||||
{{ branch.data.name_label }}
|
||||
<template #icon>
|
||||
<VtsIcon :name="hostIcon" :tooltip="hostIconTooltip" size="medium" />
|
||||
@@ -18,17 +18,17 @@
|
||||
v-tooltip="t('running-vm', runningVmsCount)"
|
||||
:value="runningVmsCount"
|
||||
accent="brand"
|
||||
variant="secondary"
|
||||
size="small"
|
||||
variant="secondary"
|
||||
/>
|
||||
<MenuList placement="bottom-start">
|
||||
<template #trigger="{ open, isOpen }">
|
||||
<UiButtonIcon
|
||||
:aria-label="t('quick-actions')"
|
||||
:selected="isOpen"
|
||||
accent="brand"
|
||||
icon="action:more-actions"
|
||||
size="small"
|
||||
:selected="isOpen"
|
||||
@click="open($event)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -29,12 +29,12 @@ export function useXoVmUtils(rawVm: MaybeRefOrGetter<FrontXoVm>) {
|
||||
|
||||
const powerState = useMapper<VM_POWER_STATE, { icon: IconName; text: string }>(
|
||||
() => vm.value.power_state,
|
||||
{
|
||||
() => ({
|
||||
[VM_POWER_STATE.RUNNING]: { icon: 'status:running-circle', text: t('vm:status:running') },
|
||||
[VM_POWER_STATE.HALTED]: { icon: 'status:halted-circle', text: t('vm:status:halted') },
|
||||
[VM_POWER_STATE.PAUSED]: { icon: 'status:paused-circle', text: t('vm:status:paused') },
|
||||
[VM_POWER_STATE.SUSPENDED]: { icon: 'status:suspended-circle', text: t('vm:status:suspended') },
|
||||
},
|
||||
}),
|
||||
VM_POWER_STATE.RUNNING
|
||||
)
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
> Users must be able to say: "I had this issue, happy to know it's fixed"
|
||||
|
||||
- [Pools] Pool side panel now shows the same pool name, UUID and icon as the pools table, and keeps the pool card when the pool is disconnected or unreachable (PR [#10714](https://github.com/vatesfr/xen-orchestra/pull/10714))
|
||||
- [Treeview] Fix translations of the tooltip for VM and host statuses in treeview (PR [#10643](https://github.com/vatesfr/xen-orchestra/pull/10643))
|
||||
|
||||
### Packages to release
|
||||
|
||||
|
||||
Reference in New Issue
Block a user